使用ctypes将C++函数导出到Python:未定义的符号

7

考虑以下包含两个类似函数的文件:

#include <iostream>

int main()
{
  std::cout << "main\n";
}

int notmain()
{
  std::cout << "notmain\n";
}

我将这个编译成了一个共享库:

g++ -shared -Wl,-soname,code -o code.so -fPIC code.cpp

我希望从Python中调用这些内容,在主函数main方面,这个方法很好用:
import ctypes
libc = ctypes.cdll.LoadLibrary("code.so")
libc.main()

这段代码打印了main,但是notmain无法运行:

import ctypes
libc = ctypes.cdll.LoadLibrary("code.so")
libc.notmain()

输出结果:
<ipython-input-63-d6bcf8b748de> in <module>()
----> 1 libc.notmain()

/usr/lib/python3.4/ctypes/__init__.py in __getattr__(self, name)
    362         if name.startswith('__') and name.endswith('__'):
    363             raise AttributeError(name)
--> 364         func = self.__getitem__(name)
    365         setattr(self, name, func)
    366         return func

/usr/lib/python3.4/ctypes/__init__.py in __getitem__(self, name_or_ordinal)
    367 
    368     def __getitem__(self, name_or_ordinal):
--> 369         func = self._FuncPtr((name_or_ordinal, self))
    370         if not isinstance(name_or_ordinal, int):
    371             func.__name__ = name_or_ordinal

我假设主函数'main'与'notmain'在代码中被外部世界(即code.so)引用的方式不同,因为在C ++规范中,'main'是一个特殊情况。如何以相同的方式“导出”'notmain'?或者说,如何解决异常? 编辑:根据@abdallahesam的建议,我向'notmain'添加了estern "C",但这并没有改变(或解决)问题。
#include <iostream>

int main()
{
  std::cout << "main\n";
}

extern "C" {
  int notmain()
  {
std::cout << "notmain\n";
  }
}

更正

这个建议确实解决了问题,我只需要重新启动(i)Python会话。显然这很重要 :)


有趣的是,nm将main函数显示为符号“00000000000008a5 T main”,而将notmain函数显示为带有类型“签名添加”的符号:00000000000008c6 T _Z7notmainv - Herbert
我遇到了同样的问题,唯一的解决方法是重新启动Python会话。在我的情况下,我需要让它在不重新启动Python会话的情况下工作。有什么线索吗? - Pablo Riera
2个回答

5

我认为你需要在notmain函数头部添加extern "C",以防止C++编译器改变函数名称。


谢谢,我按照原帖中的方法尝试了,但并没有解决问题。 - Herbert
更正:我需要重新启动我的ipython会话才能使其工作。 - Herbert
如果...只有一条语句,使用extern "C" ...extern "C" {...}都无所谓。我尝试了两种方式,都可以正常工作。 - Herbert
不管怎样,还是谢谢你!否则我可能要花好几个小时才能解决这个问题。 - Herbert

0
另一个可能的解决方案是通过ctypes将所有库动态链接到您想要打开的一个库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接