简体   繁体   English

使用Python Ctypes加载dll

[英]Loading dll using Python Ctypes

I've looked at the example given here ctypes - Beginner and followed the same steps with a different bit of C code. 我已经看过这里给出的例子ctypes - Beginner ,并使用不同的C代码执行相同的步骤。 I've built a .dll and a .lib using C code given here: http://wolfprojects.altervista.org/articles/dll-in-c-for-python/ 我使用此处给出的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;
}

In my wrapper.py I have this: 在我的wrapper.py中我有这个:

import ctypes

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

When I run the script I get this error: 当我运行脚本时,我收到此错误:

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

OSError: [WinError 193] %1 is not a valid Win32 application OSError:[WinError 193]%1不是有效的Win32应用程序

If I use 如果我使用

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

then I don't get any error on running the script. 那么我在运行脚本时没有任何错误。 But If I try to do this: 但如果我尝试这样做:

testlib.sum(3,4)

I get the error: 我收到错误:

dll = self._dlltype(name) dll = self._dlltype(name)

TypeError: 'str' object is not callable TypeError:'str'对象不可调用

The dll and the .py are in the same folder. dll和.py位于同一文件夹中。 Can anyone help me understand what's going on here. 任何人都可以帮助我理解这里发生了什么。 I've spent hours trying to figure this out, but have hit a wall. 我花了好几个小时试图解决这个问题,但已经碰壁了。 Thanks. 谢谢。

Make sure your compiler and version of Python are both 32-bit or both 64-bit. 确保您的编译器和Python版本都是32位或64位。 You can't mix, which is the cause of OSError: [WinError 193] %1 is not a valid Win32 application . 你不能混,这是OSError: [WinError 193] %1 is not a valid Win32 application的原因OSError: [WinError 193] %1 is not a valid Win32 application

Next, make sure to compile as a C program and not C++. 接下来,确保编译为C程序而不是C ++。 That's the cause of the name mangling mention in your answer. 这就是你的回答中提到的名字错误的原因。

Example (note compiler is for x86 not x64 : 示例(注意编译器适用于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

Now use a 32-bit Python: 现在使用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

If you compile as C++, you can still call functions by exporting them as C, which prevents the C++ name mangling: 如果编译为C ++,您仍然可以通过将它们导出为C来调用函数,这可以防止C ++名称变形:

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

After further digging I've found out the solution. 经过进一步的挖掘,我发现了解决方案。 The C compiler has mangled the name of the function which is why I got an Attribute error when calling the sum method. C编译器破坏了函数的名称,这就是调用sum方法时出现Attribute错误的原因。 I had to use link.exe to figure out the mangled name and then used the getattr method. 我不得不使用link.exe找出损坏的名称,然后使用getattr方法。

More details and explanation in this post: Python: accessing DLL function using ctypes -- access by function *name* fails 这篇文章中有更多细节和解释: Python:使用ctypes访问DLL函数 - 按函数* name *访问失败

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM