使用Python Ctypes加载dll

时间:2017-04-07 04:40:50

标签: python ctypes

我已经查看了此处给出的示例ctypes - Beginner,并使用不同的C代码执行了相同的步骤。我使用此处给出的C代码构建了.dll和.lib:http://wolfprojects.altervista.org/articles/dll-in-c-for-python/

  //test.c
__declspec(dllexport) int sum(int a, int b) {
    return a + b;
}

在我的wrapper.py中我有这个:

import ctypes

testlib = ctypes.CDLL("C:\\Users\\xyz\\Documents\\Python\\test.dll")

当我运行脚本时,我收到此错误:

  

self._handle = _dlopen(self._name,mode)

     

OSError:[WinError 193]%1不是有效的Win32应用程序

如果我使用

testlib = ctypes.LibraryLoader("C:\\Users\\xyz\\Documents\\Python\\test.dll")

然后我在运行脚本时没有任何错误。但如果我尝试这样做:

testlib.sum(3,4)

我收到错误:

  

dll = self._dlltype(name)

     

TypeError:' str'对象不可调用

dll和.py位于同一个文件夹中。任何人都可以帮助我理解这里发生了什么。我花了好几个小时试图解决这个问题,但已经撞墙了。感谢。

2 个答案:

答案 0 :(得分:4)

确保您的编译器和Python版本都是32位或64位。你不能混合,这是OSError: [WinError 193] %1 is not a valid Win32 application的原因。

接下来,确保编译为C程序而不是C ++。这就是你答案中提到名称错误的原因。

示例(注意编译器适用于 x86 而非 x64

C:\>cl /LD /W4 test.c
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.c
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.dll
/dll
/implib:test.lib
test.obj
   Creating library test.lib and object test.exp

现在使用 32位 Python:

C:\>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> lib = CDLL('test')
>>> lib.sum(2,3)
5

如果你编译为C ++,你仍然可以通过将它们导出为C来调用函数,这可以防止C ++名称变形:

//test.cpp
extern "C" __declspec(dllexport) int sum(int a, int b) {
    return a + b;
}

答案 1 :(得分:0)

进一步挖掘后,我发现了解决方案。 C编译器破坏了函数的名称,这就是调用sum方法时出现Attribute错误的原因。我不得不使用link.exe找出损坏的名称,然后使用 getattr 方法。

这篇文章中的更多细节和解释: Python: accessing DLL function using ctypes -- access by function *name* fails