Вопрос

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?

Это было полезно?

Решение

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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top