有关定义:
(1)__declspec(dllexport)
导出函数,即指明该函数可从DLL中调用
(2)__declspec(dllimport)
导入函数(ctypes尚没有碰到对他的具体应用)
#define EXPORT __declspec(dllexport)
EXPORT int IntAdd(int a, int b)
{
return a + b;
}
EXPORT char *hello_python()
{
//char p[] = "hi python, this is c speaking...";
char *p = "hi python, this is c speaking...";
return p;
}
先C中写两个函数,以供ctypes调用:
from ctypes import *
filename = 'test_ctypes.dll'
dll = cdll.LoadLibrary(filename)
然后就可以通过dll对象来调用C代码中的“导出函数(__declspec(dllexport))”
intadd = dll.IntAdd
intadd .argtypes设置传入参数的类型
例:addint.argtypes = [c_int, c_int]
intadd .restype设置返回类型
例:addint.restype = c_int
有参数值或者返回值时,应当指明其类型
dll = cdll.LoadLibrary(filename)
addint = dll.IntAdd
addint.argtypes = [c_int, c_int]
addint.restype = c_int
print addint(1,2)#3
print dll.IntAdd(1,2)#3 结果同样也是3,type类型为int,但如果C语言中参数及返回值类型变为了float类型此处就会出现问题
对于只有返回值而没有入参的函数:
只需设定其返回值类型
str_fun = dll.hello_python
str_fun.restype = c_char_p
print str_fun()# hi python, this is c speaking...
ctypes的数据类型映射
ctypes type | C type | Python Type |
c_char | char | 1-character string |
c_wchar | wchar_t | 1-character unicode string |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_bool | bool | bool |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned int | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 or longlong | int/long |
c_ulonglong | unsigned __int64 or unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_longdouble | long double float | float |
c_char_p | char * | string or None |
c_wchar_p | wchar_t * | unicode or None |
c_void_p | void * | int/long or None |