Python可以调用C++;使用extern编译的DLL库;";用ctypes? 因特网上有很多文章说Python不能使用 cType < /St>访问C++编译的DLL,并且还有其他矛盾的文章,只要DLL是用“C”>方法编译的,就可以访问DLL。所以我只想澄清一下。如果使用外部“C”是否可能?
有C++编译的DLL可以用于Python可以调用C++;使用extern编译的DLL库;";用ctypes? 因特网上有很多文章说Python不能使用 cType < /St>访问C++编译的DLL,并且还有其他矛盾的文章,只要DLL是用“C”>方法编译的,就可以访问DLL。所以我只想澄清一下。如果使用外部“C”是否可能?,python,c++,dll,ctypes,Python,C++,Dll,Ctypes,有C++编译的DLL可以用于ctypes和C++编译的DLL不能直接用于ctypes 如果API仅公开(例如,int、int*、char*和类似内容),并包装在extern“C”中,则可以从ctypes中使用它 如果在接口中使用了非POD类(例如std::vector或std::string),或者API没有包装在extern“C”中,则dll不能与ctypes一起使用(至少以可移植的方式,并且不需要太多的麻烦) 为什么需要外部“C” 以下声明在C++中有效,但不在C: void my_fun
ctypes
和C++编译的DLL不能直接用于ctypes
如果API仅公开(例如,int
、int*
、char*
和类似内容),并包装在extern“C”
中,则可以从ctypes
中使用它
如果在接口中使用了非POD类(例如std::vector
或std::string
),或者API没有包装在extern“C”
中,则dll不能与ctypes
一起使用(至少以可移植的方式,并且不需要太多的麻烦)
为什么需要外部“C”
以下声明在C++中有效,但不在C:
void my_fun(int a);
void my_fun(double a);
由于C不执行名称篡改,这两个函数都将映射到结果对象文件中名为my_fun
的符号,这是有问题的
C++将创建两个名称有误的不同符号,例如,gcc将创建符号Z6my\u funi
和\u Z6my\u fund
。MSVC有另一个命名方案,因此dll(或共享对象)中的结果符号取决于构建它的编译器
借助于ctypes
,在dll中找到这些符号并非不可能——它不仅不像C名称那样直截了当,因为需要更多的信息——dll是用哪个编译器构建的
C-names与ctypes
一起开箱即用,将声明包装到extern“C”
中会关闭名称混乱,因此
extern "C" {
void my_fun(int a);
void my_fun(double a);
}
将不再编译,因为编译器将确保一个符号没有多个定义
为什么更复杂的C++类不能在接口中使用?
extern“C”
并不禁止使用std::vector
和其他C++类:
extern "C" {
void my_fun(std::vector<double> a);
}
extern“C”{
无效我的乐趣(标准::向量a);
}
编译时,它只生成符号my\u func
,而不是?my\u fun@@YANV$vector@NV?$allocator@N@结果对象文件中的std@@@std@@@Z
(使用MSVC)或\u Z6my\u funst6vectoridsaide
(使用gcc)
而对于POD,比如说double[10]
,内存布局是清晰的,例如std::vector
的内存布局取决于实现,并且ctypes
不知道。另一个问题是一些ctypes
不能处理的东西,构造函数/析构函数可能比POD的简单初始化更复杂
因此,
my_-fun(std::vector)
的功能不能与ctypes一起使用。然而,如果你知道类的内存布局,你可以用ctypes
来模拟它们,通过调用()构造函数初始化对象(顺便说一句,类方法的符号总是会被损坏,即使包装在extern“C”
),调用函数my_fun
,然后通过调用(右)析构函数来销毁对象。是,当然它们看起来与DLLsI在LINUX平台上使用以下信息所做的完全相同:。我从未尝试过在Windows平台上使用Python,它不能使用C++来访问C++编译的DLL——这是不正确的,因为我维护的开源产品(C++编译的DLL)很容易用Python访问。std::vector和std::string等是唯一与ctypes不兼容的类?@roberttat相反:只有pod是兼容的,其他什么都没有。