使用Windows上的ctypes在python中包装c ++函数:找不到函数

时间:2014-07-04 13:21:59

标签: python c++ visual-studio-2012 swig ctypes

我需要运行一系列python脚本来计算各种脚本,这些脚本工作正常,但其中一个脚本运行速度很慢,必须用C ++完成。 C ++代码已准备就绪,但我需要找到一种从python调用C ++函数并获取返回值的方法。

我找到了有关SWIG的信息,但是没有让它在Windows上使用Visual Studio(我必须在Windows上使用VS,因为其他限制)。我发现使用标准输入和输出值的非常简单的函数更容易使用ctypes。

所以我用ctypes进行了很多测试,尝试了我在网上找到的所有例子,每次都会发生的事情是我可以加载dll(用visual studio 2012编译器构建)但是当我尝试调用函数时在python中,它只是:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print maLib.plop()
  File "C:\Python27\lib\ctypes\__init__.py", line 378, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python27\lib\ctypes\__init__.py", line 383, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'plop' not found

python代码是(test.py):

from ctypes import cdll
lib = cdll.LoadLibrary('test')
print lib.plop()

C ++代码是(test.cpp,编译为test.dll,Visual Studio设置为构建为dll):

extern "C"
{
    int plop();
}

int plop() { return 4; }

正如您所看到的,我尝试尽可能简单,以避免细节使其失败。我已经阅读了python ctypes帮助,以及如何使用ctypes的教程,尝试与它们完全相同的代码,但我不得不适应一点,因为我使用的是Visual Studio / windows,而其他大多数用户都在使用linux。 所有文件都在同一个文件夹中。

我尝试了多种加载库的方法:LoadLibrary('。/ name.dll'),WinDLL('name.dll'),为函数提供不同的名称,void返回类型等等......

你认为我应该使用SWIG吗?我的问题是一个明显的初学者错误吗?我是一名学生,对我正在使用的大部分内容都很陌生,但我在这方面付出了很多努力,即使我只需要它来完成一项特定的任务。 当使用SWIG时,我不得不用函数指针或引用创建一个包装器,所以我认为这是问题,这让我想尝试一个更简单的解决方案。

我正在使用:Python 2.7.7,Visual Studio 2012,Windows 8.1

非常感谢提前

2 个答案:

答案 0 :(得分:7)

Python报告的错误非常清楚。

  

功能&#39; plop&#39;找不到

这意味着DLL不会导出该名称的函数。因此,您需要导出该功能。使用.def文件或使用__declspec(dllexport)

extern "C"
{
    __declspec(dllexport) int plop();
}

要检查DLL以调试此类问题,请使用dumpbin或Dependency Walker。

请注意,由于未指定调用约定,因此使用默认值__cdecl。这意味着cdllctypes是正确的。

答案 1 :(得分:2)

您需要提供功能“C”链接以避免name mangling。声明如下:

extern "C"
{
    int plop();
}

然后它将被恰当地称为“plop”,而不是被命名为。