2013-12-18 2 views
2

Я хочу использовать классы C++ из Python с библиотекой ctypes:Python ctypes с абстрактными классами

Мои C++ Классы:

class ClassAInteface 
{ 
    protected: 
    ClassAInterface() {} 

public: 
virtual ~ClassAInteface() {} 
virtual void MethodA() = 0; 
}; 

class ConcreteClassA : public ClassAInteface 
{ 
public: 
ConcreteClassA(); 
virtual ~ConcreteClassA(); 
//ClassAInteface Methods 
void MethodA(); 
}; 
//Second class which uses the First class 
class ClassB 
{ 
    public: 
    ClassB(ClassAInteface* firstClass); 
    virtual ~ClassB(); 
    void MethodB(int param); 
} 

Теперь я хочу, чтобы использовать эти классы в Python с CTypes:

extern "C" { 
    ConcreteClassA* ConcreteClassA_new() { return new ConcreteClassA(); } 
    void MethodA(ConcreteClassA* classA) { classA->MethodA(); } 
    ClassB* ClassB_new(ConcreteClassA* classA) { return new ClassB(classA); } 
    void MethodB(ClassB* classB,int param) {dl->MethodB(param); } 
} 

Использование первого класса в Python отлично работает с: ... Импорт общих библиотек ... -> SharedLib

#Create a Python Class 
class ClassA(object): 
    def __init__(self): 
     self.obj = sharedLib.ConcreteClassA_new() 
    def MethodA(self): 
     sharedLib.MethodA(self.obj) 
objA = ClassA() 

Но когда я хочу использовать второй и первый класс вместе Pyhton с:

class ClassB(object): 
    def __init__(self,firstClass): 
     self.obj = sharedLib.ClassB_new(firstClass) 
    def Drive(self): 
     sharedLib.MethodB(self.obj,angle) 
objA = ClassA() 
objB = ClassB(objA) 

я получаю:

self.obj = sharedLib.ClassB_new(firstClass) ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1

Я думаю, что без абстрактного класса она будет работать? Но как я могу легко использовать мои классы в Python?

+0

Я удивлен, что вы можете успешно создать экземпляр абстрактного 'ClassAInteface' с момента своего конструктора' 'private' и ConcreteClassA_new()' функция не объявлена ​​'friend' ни это производный класс. Кроме того, вы не можете использовать абстрактный класс в качестве возвращаемого типа функции, поэтому функция не должна компилироваться. – martineau

+0

Функция ConcreteClass_new() - это только функция, которая создает указатель ConcreteClass, и i не требуется объявлять ее как друга или производного класса, хороший пример здесь: [link] (http://bigbang.waterlin.org/bang/use-python-ctypes-to-link-cpp-library /) – rubiktubik

+0

Функция 'ConcreteClassA_new()' возвращает указатель на динамически выделенный «ConcreteClassA' _instance_ it_creates_ через оператор' new' и конструктор по умолчанию класса. – martineau

ответ

0

Как ctypes знает, что использовать атрибут obj? Используйте _as_parameter_.

Во-первых, убедитесь, что вы задаете параметры и типы результатов. ctypes по умолчанию использует C int, что приведет к аннулированию 64-битных указателей.

sharedLib.ConcreteClassA_new.restype = c_void_p 

sharedLib.ClassB_new.restype = c_void_p 
sharedLib.ClassB_new.argtypes = [c_void_p] 

sharedLib.MethodA.restype = None 
sharedLib.MethodA.argtypes = [c_void_p] 

sharedLib.MethodB.restype = None 
sharedLib.MethodB.argtypes = [c_void_p, c_int] 

class ClassA(object): 

    def __init__(self): 
     self._as_parameter_ = sharedLib.ConcreteClassA_new() 

    def MethodA(self): 
     sharedLib.MethodA(self) 
Смежные вопросы