为什么我需要__declspec(dllexport)才能使某些函数可从ctypes访问?
因此,我正在学习利用Python ctypes模块。
这是我在Windows上使用gcc -shared(版本4.8)进行编译以获取示例.dll的简单C文件:
#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是结构的typedef。我使用GCC进行编译,并且可以像以前一样访问该函数,但是当我删除__declspec(dllexport)或_
stdcall(或两者)时,该函数将不再可用。
我的问题是,为什么我可以从第一个示例访问简单功能,却无法访问更复杂的功能,这是什么原因?_编译C代码并从ctypes访问它时 ,使用调用约定/
_declspec _的规则是什么 ?
-
gcc
似乎默认情况下会导出功能,您可以使用任何PE查看器(例如PE Explorer)(“查看”>“导出”)查看导出的功能:但是,如果尝试使用VC ++编译此代码,它将不会为您导出此函数,您会看到没有导出的函数:
您需要要求它导出此功能:
__declspec(dllexport) int addition(int a, int b){ return a+b; }
至于调用约定,规则很简单:
如果您的函数使用
__stdcall
,作为大多数Win32API,则需要使用WinDLL('mylib.dll')
或导入DLL
windll.mylib
,例如:> 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')
或导入DLLcdll.mylib'
,例如:> 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 >>>