ctypes 封装c语言

一,python与C类型对应关系

最左边一列的ctypes type,以替代C库中的各种类型。

二,不带参数的调用

1,target.c

#include <stdio.h>

void hello_world(){
    printf("hello downey!!\r\n");
}

2,执行命令编译动态连接库文件

gcc -shared -o libtarget.dll target.c

        linux:
        gcc --shared -fPIC -o target.c libtarget.so
        windows:
        gcc -shared -o libtarget.dll target.c

3,test.py

import ctypes

if __name__ == '__main__':
    test = ctypes.windll.LoadLibrary("./libtarget.dll")
    test.hello_world()

4,输出

hello downey!!

三,带参数的调用

1,target.c

#include <stdio.h>

char add(int a, int b){
    return a + b;
}

char mul(int a, int b){
    return a * b;
} 

2,执行编译命令

    gcc -shared -o libtarget.dll target.c

3,test.py

from ctypes import *


if __name__ == '__main__':

    # windll.LoadLibrary("./libtarget.dll")  # woinows应该用windll ,但用cdll在windows下测试也没问题。
    test = cdll.LoadLibrary("./libtarget.dll") # linux 用cdll

    test.add.restype = c_int
    test.mul.restype = c_int

    c = test.add(48,22)
    print(type(c))
    print(c)

    d = test.mul(48, 22)
    print(d)

4,输出

<class 'int'>
70
1056

四,结构体数据格式

1,target.c

#include <stdio.h>
#include <string.h>


typedef struct{
    char *ptr;
    float f;
    char array[10];
}target_struct;

target_struct* hello_world(target_struct* target){

    static char temp = 0x30;
    target->ptr = &temp;
    target->f = 3.1;
    memset(target->array,1,sizeof(target->array));
    return target;
}

2,执行编译命令

    gcc -shared -o libtarget.dll target.c

3,test.py

from ctypes import *

# 声明一个和结构体数据对应的数据结构类 
# _fields_是字典类型,key要与C库中结构体相对应,value则是指定相应类型
class test_struct(Structure):
    _fields_ = [('ptr', c_char_p),

                ('c', c_float),

                ('array', c_char * 10)]


if __name__ == '__main__':
    test = windll.LoadLibrary("./libtarget.dll")

    # 构造一个对应C中结构体的类,可以传入对应参数进行构造。
    struct = test_struct(c=0.5)

    #指定返回值类型为test_struct指针类型,这里的类型由POINTER()修饰,表示是指针类型
    test.hello_world.restype = POINTER(test_struct)

    # 调用hello_world()函数,传入struct类,pointer(struct)就是将struct转为指针类型实例。因为在C中的接口就是传入target_struct类型,返回target_struct类型,所以ret_struct也是target_struct*类型
    ret_struct = test.hello_world(pointer(struct))

    # 打印函数返回值,查看执行结果。对于一个指针类型的变量,如果我们要获取它的值,可以使用.contents方法
    print(ret_struct.contents.ptr)
    print(ret_struct.contents.c)

4,输出

b'0'
3.0999999046325684   # 浮点数3.1 在python中的表示

五,参数传入函数引用,c调用python函数

1,target.c

#include <stdio.h>
#include <string.h>


typedef void (*callback)(int);

void func(callback c1,callback c2,int p1,int p2){

    c1(p1);
    c2(p2);
}

2,执行编译命令

 gcc -shared -o libtarget.dll target.c

3,test.py

from ctypes import *


def test_callback1(val):
    print("I'm callback1")
    print(val)


def test_callback2(val):
    print("I'm callback2")
    print(val)


if __name__ == '__main__':
    test = windll.LoadLibrary("./libtarget.dll")

    CMPFUNC = CFUNCTYPE(None, c_int)

    cbk1 = CMPFUNC(test_callback1)

    cbk2 = CMPFUNC(test_callback2)

    test.func(cbk1, cbk2, 1, 2)

4,输出

I'm callback1
1
I'm callback2
2

windos 安装gcc:

Mingw快捷安装教程 并完美解决出现的下载错误:The file has been downloaded incorrectly_mingw the file has been downloaded incorrectly-CSDN博客

参考:

python代码用c语言封装_python调用C语言接口-CSDN博客

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值