2

I'm trying to use some C++ method in my python code and I'm using ctypes library. I have wrote a simple C++ code using a simple main with no arguments and another simple method named printArgs which takes an argument of type char *. I also have wrote a simple python code to import these two methods. I made two linked libraries(one .so and one .a because I'm using Debian) with this command:

g++ -o hello.so -shared -fPIC hello.cpp 

And then used export LD_LIBRARY_PATH=/the/path/to/the/linked/libraries/directory.

There is no problem in getting the main method, bu when I'm trying to get printArgs I get AttributeError. Here's the C++ code:

#include <iostream>
using namespace std;

int printArgs(char * args_array){
    for (int i = 0; i < 5; i++){
        cout<<i<<"- "<<args_array[i]<<"\n";
    }
    return 0;
}

int main(){
    cout<<"Hello\n";
    return 0;
}

Here's the Python code:

from ctypes import *
helloInCPP_lib = cdll.LoadLibrary("hello.a")
print helloInCPP_lib
helloInCPPMain = helloInCPP_lib.main
print helloInCPPMain
helloInCPPPrint = helloInCPP_lib.printArgs
print helloInCPPPrint

I get this output:

<CDLL 'hello.a', handle 9c45488 at b73d1e6c>
<_FuncPtr object at 0xb73e67e4>
Traceback (most recent call last):
    File "testHelloInCPP.py", line 9, in <module>
        helloInCPPPrint = helloInCPP_lib.printArgs(None)
    File "/usr/lib/python2.6/ctypes/__init__.py", line 366, in __getattr__
        func = self.__getitem__(name)
    File "/usr/lib/python2.6/ctypes/__init__.py", line 371, in __getitem__
        func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /etc/linked_libraries/hello.a: undefined symbol: printArgs

I also tried cdll.LoadLibrary("hello.so") and/or helloInCPPPrint = helloInCPP_lib.printArgs(None); got the same error in both conditions. Any idea?

I'm using Debian 32 bit on a VMWare Workstation and Python 2.6.

2 Answers 2

3

Declare the printArgs using extern "C":

#include <iostream>
using namespace std;

extern "C" {
    int printArgs(char * args_array);
}

int printArgs(char * args_array){
    for (int i = 0; i < 5; i++){
        cout<<i<<"- "<<args_array[i]<<"\n";
    }
}

int main(){
    cout<<"Hello\n";
}

BTW, you should pass a string (c_char_p), not None:

...
helloInCPPPrint = helloInCPP_lib.printArgs
helloInCPPPrint.argtypes = [c_char_p]
print helloInCPPPrint("ABCDE")

About argtypes, see Specifying the required argument types (function prototypes).

Sign up to request clarification or add additional context in comments.

7 Comments

I have got Segmentation fault for printArgs.
@ZeinabAbbasi, What did you pass to printArg ? None ??
@ZeinabAbbasi, I updated the answer with slightly modified Python code. Check it out.
Thank you, that was the answer.
@ZeinabAbbasi, See restype and Return types.
|
0

I tired compiling the solution by @falsetru using

g++ -O3 -shared -std=c++11 -fPIC code.cpp -o lib.so

but could not without this small modification to code.c, according to the link provided in their answer extern "C":

#include <iostream>
using namespace std;

extern "C" int printArgs(char * args_array){
    for (int i = 0; i < 5; i++){
        cout<<i<<"- "<<args_array[i]<<"\n";
    }
}

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.