2

I am trying to write a c routine to speed up a python script.

In order to route prove my method I first wrote a short test c function and compiled it into a library: the code for the test function is:

void cttest(void);
#include <stdio.h>

void cttest()
{
    printf("This is the shared module|n");
    return;
}

I saved this code into a file 'ct_test.cc'.

I then compiled this code as follows:

g++ -shared -fPIC -o /home/paula/libs/libcttest.so ct_test.cc

which gave no errors or warnings.

I then loaded ipython and typed the following:

import ctypes as ct

test=ct.CDLL("/home/paula/libs/libcttest.so")

if I now try to access the function (by typing 'test.' and then hitting tab) nothing happens.

If I do this:

What am I doing wrong?

Oh, just in case it makes any difference:

OS: xubuntu 14.10 Python: 2.7.8 ipython: 2.3.0 g++ : 4.9.1

9
  • The syntax used at docs.python.org/2/library/… is different. You could try their suggestion. Commented Jan 10, 2015 at 5:56
  • Thank you very much for taking the time to comment and for your suggestion. I have now tried the 'cdll.LoadLibrary' syntax and the result is the same. Commented Jan 10, 2015 at 6:26
  • Type test.cttest(). Don't assume tab-completion works. Commented Jan 10, 2015 at 7:52
  • 1
    Using C++, the name stored in the library will differ from just 'cttest' (there's name mangling). To prevent this, add extern "C" just before your first line to inform g++ that the C-style name should be stored instead. Commented Jan 10, 2015 at 9:50
  • 1
    I am delighted to tell you all that brm is right! Thankyou all for your help Commented Jan 10, 2015 at 10:42

1 Answer 1

3

You have two problems:

  1. Firstly as has already been noted tab auto-complete won't work for ctypes until a function has been used for the first time. (It wouldn't be impossible to make it work on most platforms, but it would add a fair overhead to loading the library I suspect).
  2. You've written C and you're trying to call it like C, but you used a C++ compiler so you have a name mangling problem.

The solution to the first problem is trivial - use the full name and don't rely on auto-completion. There are at least 3 solutions to the second, I've written them here from best to worst:

  1. Use a C compiler instead of C++ compiler. (gcc instead of g++).
  2. Use extern "C" to force the C++ compiler to not mangle the function name:

    extern "C" void cttest(void);
    
    extern "C" 
    {
        void cttest()
        {
            printf("This is the shared module\n");
            return;
        }
    }
    
  3. Use the mangled C++ name in Python, in this case it would be _Z6cttestv

To prove that this works I tried it out on Ubuntu 14.04:

gcc -shared -fPIC -o libcttest.so test.c

And using it in ipython:

ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:38) 
Type "copyright", "credits" or "license" for more information.

IPython 1.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import ctypes as ct

In [2]: test=ct.CDLL('./libcttest.so')

In [3]: test.cttest()
This is the shared module
Out[3]: 26
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.