访问C++编译的DLL,并且还有其他矛盾的文章,只要DLL是用“C”>方法编译的,就可以访问DLL。所以我只想澄清一下。如果使用外部“C”是否可能?,python,c++,dll,ctypes,Python,C++,Dll,Ctypes" /> 访问C++编译的DLL,并且还有其他矛盾的文章,只要DLL是用“C”>方法编译的,就可以访问DLL。所以我只想澄清一下。如果使用外部“C”是否可能?,python,c++,dll,ctypes,Python,C++,Dll,Ctypes" />

Python可以调用C++;使用extern编译的DLL库;";用ctypes? 因特网上有很多文章说Python不能使用 cType < /St>访问C++编译的DLL,并且还有其他矛盾的文章,只要DLL是用“C”>方法编译的,就可以访问DLL。所以我只想澄清一下。如果使用外部“C”是否可能?

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

有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(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是兼容的,其他什么都没有。