2

我希望能够使用 ctypes python 模块从 python 中使用 C/C++ 函数。

int doit().c/.cpp文件中有一个函数。当我尝试加载共享库时:

Frr=CDLL("/path/FoCpy2/libFrr.so")
Frr.doit(c_int(5))

.c我发现使用该变体时它工作得非常好。当调用 C++ 时,调用此函数的好方法是(使用nm libFrr.sousing发现nm -gC libFrr.so只是简单的生成doit()):

Frr._Z4doitv(c_int(5))

我在 Stackexchange 上读到没有从 python 调用 C++ 的标准方法,并且存在“非标准名称修改”问题。“Z4”是那个问题的一部分吗?我猜非标准名称修饰会出现在更高级的语言功能(如类方法、模板)中,但也适用于这些基本功能?是否可以在 C++ 代码的简单情况下强制使用简单的 C 函数名称?

4

2 回答 2

2

调用 c++ 库函数总是一团糟,实际上即使您使用的是 C++,您也必须使用相同的编译器等以确保其正常工作。

唯一通用的解决方案是将您的 c++ 函数定义为extern "C"并确保遵循相关限制 - 请参阅此处以获取解释。

于 2012-12-14T22:10:57.943 回答
2

您可以使用extern "C"使函数“看起来像”外部世界的 C 函数(即禁用名称修饰)。是的,你是对的,C++ 拥有的更复杂的特性和函数类型主要需要名称修饰,并且名称修饰方案从未标准化(也没有二进制兼容性),因此它因编译器而异以及版本之间(但大多数主流编译器现在已经解决了一些永久性的问题,但编译器供应商之间仍然不同)。并且对于普通的旧自由函数也需要重载的原因是因为 C++ 支持重载(相同的函数名称但具有不同的参数),因此,编译器会将参数规范(例如,类型)编码为重载名称。当然,如果你使用extern "C"您会失去所有需要名称修饰的功能,因此,它或多或少只能归结为 C 函数。

您可以extern "C"在每个功能的基础上使用任何一个,如下所示:

extern "C" int doit();

或者对于整体标题:

extern "C" {

// all the function declarations here ...

};

但是,特别是对于 Python,我强烈建议您使用一个库,该库允许您构建 Python 类和函数,这些类和函数反映了您的 C++ 类和函数,这使生活变得更加轻松,并隐藏了所有这些外部“C”业务. 我建议使用Boost.Python,请参阅此入门页面,它使将函数和类导出到 Python 变得轻而易举。我想其他人也会推荐SWIG,但我从未使用过它。

于 2012-12-14T22:35:02.660 回答