Python ctypes module is very convenient for python to integrate C module.
Win7 X64 examples:
1) Call c dll library passing in arguments and return structure ptr
C lib:
-----------------------------------------------------------------------------------------
return_structure_ptr.h
#ifndef __RETURN_STRUCTURE_PTR_H__
#define __RETURN_STRUCTURE_PTR_H__
struct Dummy
{
int a;
double d;
char str[64];
};
#define DLLEXPORT __declspec(dllexport)
DLLEXPORT struct Dummy* return_structure_ptr(int a, int d, const char *str);
#endif /*__RETURN_STRUCTURE_PTR_H__*/
return_structure_ptr.c
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include "return_structure_ptr.h"
DLLEXPORT struct Dummy* return_structure_ptr(int a, double d, const char *str)
{
struct Dummy* dummy = (struct Dummy*) malloc (sizeof(struct Dummy));
dummy->a = a;
dummy->d = d;
strcpy(dummy->str, str);
printf("%d, %f, %s\n", a, d, str);
return dummy;
}
DLLEXPORT void free_dummy_struture(struct Dummy* pd)
{
free(pd);
printf("0x%x\n", pd);
}
-------------------------------------------------------------------------------------------
Build the above c file to return_structure_ptr.dll. Note that the target architecture should be the same as Python's, say if Python is x64, the dll should be built for X64.
Otherwise, Python ctypes module will fail to load the dll.
VS tips:
VS2012 -> Project -> return_structure_ptr Properties -> Configuration Properties -> Linked -> Advanced -> Target Machine -> Pick "MachineX64"
VS2012 -> Build -> Configuration Manager -> Active Solution Platform -> New -> x64, also change the return_structure_ptr project in the following grid to x64 in the "Platform" column.
--------------------------------------------------------------------------------------------
Python code which load the dll:
from ctypes import *
class Dummy(Structure):
_fields_ = [('a', c_int), ('d', c_double), ('str', c_byte * 64)]
if __name__ == '__main__':
dll_handle = CDLL('return_structure_ptr.dll')
dll_handle.return_structure_ptr.restypes = POINTER(Dummy)
dll_handle.return_structure_ptr.argtypes = [c_int, c_double, c_char_p]
res_ptr = dll_handle.return_structure_ptr(c_int(10), c_double(40.123), c_char_p(b'hello'))
res_ptr = cast(res_ptr, POINTER(Dummy))
print(res_ptr.contents.a)
print(res_ptr.contents.d)
print(''.join(map(chr, res_ptr.contents.str)))
dll_handle.free_dummy_struture(res_ptr)
2) Passing in structure ptr as argument to C from Python and return the structure from C
C code:
head file:
DLLEXPORT struct Dummy* passing_in_and_return_structure(struct Dummy* pd);
C source file:
DLLEXPORT struct Dummy* passing_in_and_return_structure(struct Dummy* pd)
{
printf("%d, %f, %s, 0x%x\n", pd->a, pd->d, pd->str, pd);
pd->a = 1234;
pd->d = 5678.0;
strcpy(pd->str, "changed");
return pd;
}
Python Code
---------------------------------------------------------------------------------------------
dummy = Dummy()
dummy.a = c_int(1)
dummy.d = c_double(2.0)
for i, c in enumerate('xxx'):
dummy.str[i] = ord(c)
dll_handle.passing_in_and_return_structure(byref(dummy))
print(dummy.a, dummy.d, ''.join(map(chr, dummy.str)))
3) Passing in array as argument to C from python and return the array from C
C code:
head file:
DLLEXPORT int* passing_in_and_return_array(int *arr, int siz);
Source file:
DLLEXPORT int* passing_in_and_return_array(int *arr, int siz)
{
int i = 0;
for (; i < siz; i++)
{
printf("%d ", arr[i]);
arr[i] = i + 10;
}
printf("\n");
return arr;
}
Python code:
--------------------------------------------------------------------------------------------
INT_ARR = c_int * 10
a = INT_ARR()
for i in range(10):
a[i-1] = i
b = dll_handle.passing_in_and_return_array(a, len(a))
b = cast(b, POINTER(INT_ARR))
for i in range(10):
print(b.contents[i], end=' ')
本文详细介绍了如何使用Python的ctypes模块方便地将C模块整合到Python中,包括调用dll库、传递结构体指针及数组,并在Python中返回结构体。通过实例演示了如何在不同平台下构建dll文件,以及如何在Python中加载和操作dll中的函数与数据。
1万+

被折叠的 条评论
为什么被折叠?



