共享库符号名称

时间:2012-12-14 22:02:49

标签: c++ python c interop ctypes

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

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

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

我发现使用.c变体时效果非常好。当调用C ++时,调用此函数的好方法是(使用nm libFrr.so使用nm -gC libFrr.so找出只生成普通doit()):

Frr._Z4doitv(c_int(5))

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

2 个答案:

答案 0 :(得分:2)

调用c ++库函数总是一团糟,实际上即使你使用的是C ++,也必须使用相同的编译器等,以确保它有效。

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

答案 1 :(得分: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,请参阅此getting started page,它可以轻松地将函数和类导出到Python。我想其他人也会推荐SWIG,但我从未使用它。