Reputation: 96
I'm writing a Python app and I need to be able to call the C++ function getRankOfSeven
from the file SevenEval.cpp
from the project SpecialKEval. I have to run the C++ version of SpecialKEval instead of the python version for the obvious reason of performance, as the point of my app is a Monte Carlo simulation which calculates wining probabilities.
I've compiled those files:
g++ -o SevenEval.so -shared -fPIC FiveEval.cpp SevenEval.cpp
And imported the output to Python:
from ctypes import cdll
se = cdll.LoadLibrary('./SevenEval.so')
This loads without problems, but se.SevenEval()
throws AttributeError: ./SevenEval.so: undefined symbol: SevenEval
I've read that in order for ctypes to work I need to have C objects/functions instead of C++ ones, and that that is done wrapping them with extrect "C" {
, but I don't know any C/C++ (I only code in Python) so I have no idea how to do it, and the examples are too simple to adapt to my problem.
I've searched a lot before asking, maybe the solution is out there, but due to my low level of C/C++ I don't know how to do it. If someone could give me some guidelines, detailed example, or do this for me I would be very happy.
Note: Running on Ubuntu 13.10 64bit, Python2.7
Edit after Smoothware comment.
Ok, this is the declaration of the function on SevenEval.h:
short getRankOfSeven(const int CARD1, const int CARD2, const int CARD3, const int CARD4, const int CARD5, const int CARD6, const int CARD7);
And this is what I added at the end of the file:
extern "C" {
SevenEval* SevenEval_new(){ return new SevenEval(); }
short SevenEval_getRankOfSeven(SevenEval* foo, const int CARD1, const int CARD2, const int CARD3, const int CARD4, const int CARD5, const int CARD6, const int CARD7){ foo->getRankOfSeven(CARD1, CARD2, CARD3, CARD4, CARD5, CARD6, CARD7);}
}
And this is my Python file:
from ctypes import cdll
lib = cdll.LoadLibrary('./SevenEval.so')
class SevenEval(object):
def __init__(self):
self.obj = lib.SevenEval_new()
def getRankOfSeven(self, c1, c2, c3, c4, c5, c6, c7):
lib.SevenEval_getRankOfSeven(self.obj, c1, c2, c3, c4, c5, c6, c7)
se = SevenEval() # Runs OK
print se.getRankOfSeven(1,2,3,4,5,6,7) # Gives Segmentation fault (core dumped)
What have I done wrong?
Upvotes: 1
Views: 218
Reputation: 96
The solution in the last edit works on 32-bit Python. For 64-bit:
from ctypes import cdll
from ctypes import c_void_p
lib = cdll.LoadLibrary('./SevenEval.so')
lib.SevenEval_new.restype = c_void_p
class SevenEval(object):
def __init__(self):
self.obj = c_void_p(lib.SevenEval_new())
def getRankOfSeven(self, c1, c2, c3, c4, c5, c6, c7):
return lib.SevenEval_getRankOfSeven(\
self.obj, c1, c2, c3, c4, c5, c6, c7)
Upvotes: 1