如何使用C++;使用ctypes的类? 我刚刚开始使用cType,希望使用一个C++类,我使用Cype在Python中导出了一个DLL文件。 所以让我说我的C++代码看起来像这样: class-MyClass{ 公众: int测试(); ...

如何使用C++;使用ctypes的类? 我刚刚开始使用cType,希望使用一个C++类,我使用Cype在Python中导出了一个DLL文件。 所以让我说我的C++代码看起来像这样: class-MyClass{ 公众: int测试(); ...,c++,python,ctypes,C++,Python,Ctypes,我知道创建一个包含此类的.dll文件,然后使用ctypes在python中加载.dll文件。 现在我如何创建一个MyClass类型的对象并调用它的测试函数?这是不是可能的cType?或者我会考虑使用SWIG或Booost。Python,但是ctype似乎是小项目最简单的选择。 < P>短的是,对于C++来说,没有C的标准二进制接口。编译器会为同一C++动态库输出不同的二进制文件,这是由于名称处理和处理库函数调用之间的堆栈的不同方式。 >不幸的是,实际上,没有一种可移植的方式来访问C++库。但是

我知道创建一个包含此类的.dll文件,然后使用ctypes在python中加载.dll文件。
现在我如何创建一个MyClass类型的对象并调用它的测试函数?这是不是可能的cType?或者我会考虑使用SWIG或Booost。Python,但是ctype似乎是小项目最简单的选择。

< P>短的是,对于C++来说,没有C的标准二进制接口。编译器会为同一C++动态库输出不同的二进制文件,这是由于名称处理和处理库函数调用之间的堆栈的不同方式。 <> >不幸的是,实际上,没有一种可移植的方式来访问C++库。但是,对于一个编译器,一点也没有问题。

也有一个简短的概述,为什么现在这个方法不能工作。也许在C++ 0x出来之后,我们将有一个C++标准的ABI?在那之前,你可能不会有任何方法来通过Python的代码> C++类型> /COD> .< /P> < P>除了Boost。Python。(这可能是一个更友好的解决方案,它需要一个一对一的C++类到Python类的映射)这是一个C接口的解决方案,它是一个解决方案,它有很多的优点,但是我会为那些不熟悉技术的人提供它。对于完全的公开,用这种方法,一个不会连接C++到Python,而是C++ C++到Python。下面我会介绍一个满足你的请求的例子。向您展示C++编译器的外部“C”设施的一般概念。

//YourFile.cpp (compiled into a .dll or .so file)
#include <new> //For std::nothrow
//Either include a header defining your class, or define it here. 

extern "C"  //Tells the compile to use C-linkage for the next scope.
{
    //Note: The interface this linkage region needs to use C only.  
    void * CreateInstanceOfClass( void )
    {
        // Note: Inside the function body, I can use C++. 
        return new(std::nothrow) MyClass;
    }

    //Thanks Chris. 
    void DeleteInstanceOfClass (void *ptr)
    {
         delete(std::nothrow) ptr; 
    }

    int CallMemberTest(void *ptr)
    {

        // Note: A downside here is the lack of type safety. 
        // You could always internally(in the C++ library) save a reference to all 
        // pointers created of type MyClass and verify it is an element in that
        //structure. 
        //
        // Per comments with Andre, we should avoid throwing exceptions.  
        try
        {
            MyClass * ref = reinterpret_cast<MyClass *>(ptr);
            return ref->Test();
        }
        catch(...)
        {
           return -1; //assuming -1 is an error condition. 
        }
    }

} //End C linkage scope.
在python代码中,您可以执行如下操作(显示2.7中的交互式提示):

< P>我确信BooS.Python在引擎盖下做了一些类似的事情,但是也许理解较低层的概念是有帮助的。如果你试图访问C++库的功能,我会更感兴趣,并且不需要一对一的映射。
<> P>关于C/C++交互的更多信息,请从Sun中查看这个页面:

< P>这是一个简短的解释,说明如何在Python中使用C+Type的C和C++。

这本书很好,但不完整(至少对我来说)

在我的系统(使用GCC和G++6.3.0以及Python 3.5.3的Debian Stretch x64)上,我在调用访问类的成员值的成员函数时就遇到了segfaults。 通过将指针值打印到stdout,我判断包装器中64位上编码的void*指针在Python中表示为32位。因此,当它被传递回成员函数包装器时,会出现大问题

我找到的解决方案是改变:

spam = myLib.CreateInstanceOfClass()
进入

因此缺少两件事:将返回类型设置为c_void_p(默认值为int),然后创建一个c_void_p对象(不仅仅是一个整数)

我希望我能写一篇评论,但我仍然缺少27个代表点。

扩展并回答我将通过以下方式完成类对象实例的创建:
stdc=c\u void\u p(cdll.LoadLibrary(“libc.so.6”))
使用
ctypes
c\u void\u p
数据类型可以确保在python中正确表示类对象指针


还要确保dll的内存管理由dll处理(dll中分配的内存也应该在dll中释放,而不是在python中释放)!

的确,这有点乏味,但它确实有效。不过,您会特别想注意异常。我认为假设
ctypes
模块处理抛出异常的C函数很好是不安全的。尤其是
return new MyClass;
语句非常危险,因为它可能引发
std::bad_alloc
。请添加一个
DestroyInstanceOffClass()函数也是。这是一个很好的观点。我将编辑这个例子来使用不抛出变体。另一个技巧是捕捉C++ C++函数体中的一个尝试块中的所有异常。请考虑下面的Gabriel Devillers回答,用64位库来修复内存问题。- 1。问题是关于C++类,但是该链接只给出了一个免费函数的例子。此外,不包含任何其他实际信息的URL的答案应该作为注释发表。
>>> from ctypes import cdll
>>> stdc=cdll.LoadLibrary("libc.so.6") # or similar to load c library
>>> stdcpp=cdll.LoadLibrary("libstdc++.so.6") # or similar to load c++ library
>>> myLib=cdll.LoadLibrary("/path/to/test.so")
>>> spam = myLib.CreateInstanceOfClass()
>>> spam
[outputs the pointer address of the element]
>>> value=CallMemberTest(spam)
[does whatever Test does to the spam reference of the object] 
spam = myLib.CreateInstanceOfClass()
Class_ctor_wrapper = myLib.CreateInstanceOfClass
Class_ctor_wrapper.restype = c_void_p
spam = c_void_p(Class_ctor_wrapper())