C module with ctypes

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=' ')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值