所以我正在学习如何使用Python ctypes模块 这是我在Windows上使用gcc -shared(版本4.8)编译的简单C文件,以获取示例.dll:
#include <stdio.h>
int addition(int a, int b){
return a+b;
}
我现在可以像这样从Python访问它:
>>>from ctypes import *
>>>mylibc = CDLL(r"somepath\mysample.dll")
>>>mylibc.addition
<_FuncPtr object at 0x00000000031456C8>
>>>mylibc.addition(2,3)
5
现在我尝试使用包含此功能的不同,更大和更复杂的.c文件:
__declspec(dllexport) void __stdcall
flopequity(HW hero[], HW villain[], double hcounters[],
double vcounters[], double hsums[], double vsums[], ulong board,
__int32 lenh, __int32 lenv)
其中HW是struct的typedef。我使用GCC编译它并且可以像以前那样访问该函数但是当我删除__declspec(dllexport)或_ stdcall(或两者)时,该函数不再可访问。
我的问题是,我可以从第一个例子中访问简单函数,但是我无法访问更复杂的函数。
在编译C代码并从ctypes访问它时使用调用约定/ _declspec有哪些规则?
答案 0 :(得分:4)
gcc
似乎默认导出函数,您可以使用PE Explorer(View&gt; Export)等任何PE查看器来查看导出的函数:
但是,如果您尝试使用VC ++编译此代码,它将不会为您导出此函数,您将看到没有导出函数:
您需要让它导出此功能:
__declspec(dllexport) int addition(int a, int b){
return a+b;
}
至于调用约定,规则很简单:
如果您的函数使用__stdcall
,与大多数Win32API一样,则需要使用WinDLL('mylib.dll')
或windll.mylib
导入DLL,例如:
> type mylib.c
__declspec(dllexport) int __stdcall addition(int a, int b) {
return a+b;
}
***********************************************************************
> cl mylib.c /link /dll /out:mylib.dll
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
mylib.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
/out:mylib.exe
/dll
/out:mylib.dll
mylib.obj
Creating library mylib.lib and object mylib.exp
***********************************************************************
> python
>>> from ctypes import *
>>>
>>> WinDLL('mylib.dll').addition(1, 2)
3
>>> windll.mylib.addition(1, 2)
3
>>>
如果您的函数使用__cdecl
,则witch是默认的调用约定,您需要使用CDLL('mylib.dll')
或cdll.mylib'
导入DLL,例如:
> type mylib.c
// `__cdecl` is not needed, since it's the default calling convention
__declspec(dllexport) int addition(int a, int b){
return a+b;
}
***********************************************************************
> cl mylib.c /link /dll /out:mylib.dll
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
mylib.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
/out:mylib.exe
/dll
/out:mylib.dll
mylib.obj
Creating library mylib.lib and object mylib.exp
***********************************************************************
> python
>>> from ctypes import *
>>>
>>> CDLL('mylib.dll').addition(1, 2)
3
>>> cdll.mylib.addition(1, 2)
3
>>>