• python3 中调用 C 语言的函数


    python3 中调用 C 语言的函数

    一, 先用 C 语言写好一个函数库

    my_math.c

    #include
    int add(int num1, int num2)
    {
    	return num1 + num2;
    }
    
    int sub(int num1, int num2)
    {
    	return num1 - num2;
    }
    
    int mul(int num1, int num2)
    {
    	return num1 * num2;
    }
    
    int div(int num1, int num2)
    {
    	return num1 / num2;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    二, 然后使用 gcc 编译成动态库

    gcc -c -fPIC my_math.c
    gcc -shared my_math.o -o my_math.so
    
    • 1
    • 2

    三, 使用 python 的 ctypes 库导入该静态库

    #!/opt/python3/bin/python3
    #
    from ctypes import *
    import os
    
    print("begin ......")
    libmathpath = os.path.join(os.getcwd(),"math.so")
    print(libmathpath)
    libmath = CDLL(libmathpath)
    print("-----------------")
    print(" ADD: 21 89")
    print(libmath.add(21,89))
    print("-----------------")
    print(" SUB: 124 89")
    print(libmath.sub(123,89))
    print("-----------------")
    print(" MUL: 12 77")
    print(libmath.mul(12,77))
    print("-----------------")
    print(" DIV: 183 3")
    print(libmath.div(183,3))
    print("-----------------")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    4, 执行结果如下:

    begin ......
    /home/git/math.so
    -----------------
     ADD: 21 89
    110
    -----------------
     SUB: 124 89
    34
    -----------------
     MUL: 12 77
    924
    -----------------
     DIV: 183 3
    61
    -----------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    如图 1(math.c 源码
    如图 2(testmath.py)源码
    如图 3(执行结查)

    特例使用

    . /opt/fsl-imx-xwayland/5.4-zeus/environment-setup-aarch64-poky-linux
    $CC  -c -fPIC my_math.c
    $CC -shared my_math.o -o my_math.so
    
    scp my_math.so root@192.168.99.46:/home/root/
    
    • 1
    • 2
    • 3
    • 4
    • 5

    /home/root/my_math.so

    >>> from ctypes import *
    >>> import os
    >>> libmath = CDLL("/home/root/my_math.so")
    >>> print(libmath.add(21,89))
    110
    >>> print(libmath.sub(123,89))
    34
    >>> libmath.mul(12,77)
    924
    >>> libmath.div(183,3)
    61
    >>>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    python 调用C 常用参数传递

    环境ubuntu 16.04 python3
    https://blog.csdn.net/MrCheny/article/details/79022973
    1.pycall.c

    #include 
    #include 
    struct test
    {
            int key;
            char* val;
    };
     
    //传递数值
    int ValTest(int n)
    {
            printf("val:%d\n", n);
            return 0;
    }
     
    //传递字符串
    int strTest(char* pVal)
    {
            printf("val:%s\n", pVal);
            return 0;
    }
     
    //传递结构体
    int StructTest(struct test data)
    {
            printf("key:%d,val:%s\n", data.key, data.val);
            return 0;
    }
     
    //传递结构体指针
    int PointTest(struct test* pData)
    {
            printf("key:%d,val:%s\n", pData->key, pData->val);
            return 0;
    }
     
    //传递数组
    int szTest(int a[], int nLen)
    {
            for(int i = 0; i < nLen; i++)
            {
                    printf("%d ", a[i]);
            }
            printf("\n");
            return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    11

    $CC  -c -fPIC pycall.c
    $CC -shared pycall.o -o pycall.so
    
    • 1
    • 2

    scp pycall.so root@192.168.99.46:/home/root/

    2.pycall.py

    # -*- coding: utf8 -*-
     
    import ctypes
    from ctypes import *
     
    print ('*' * 20)
    print ("传递数字")
    func = ctypes.cdll.LoadLibrary("./pycall.so")
    func.ValTest(2)
     
    print ('*' * 20)
    print ("传递字符串")
    val = bytes('qqqqqq',encoding='utf-8')
    func.strTest(val)
     
    print ('*' * 20)
    print ("传递结构体")
    class testStruct(Structure):
            _fields_=[('key',c_int),('val',c_char_p)]
     
    s = testStruct()
    s.key = 1
    s.val = bytes('test',encoding='utf-8');
    func.StructTest(s)
     
    print ('*' * 20)
    print ("传递结构体指针")
    func.PointTest(byref(s))
     
    print ('*' * 20)
    print ("传递数组")
    INPUT = c_int * 10
    data = INPUT()
    for i in range(10):
            data[i] = i
     
    func.szTest(data,len(data))
    print ('*' * 20)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    python3 pycall.py

    ********************
    传递数字
    val:2
    ********************
    传递字符串
    val:qqqqqq
    ********************
    传递结构体
    key:1,val:test
    ********************
    传递结构体指针
    key:1,val:test
    ********************
    传递数组
    0 1 2 3 4 5 6 7 8 9
    ********************
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    16.16. ctypes — A foreign function library for Python

    https://docs.python.org/3.6/library/ctypes.html#structures-and-unions

    python3 ctypes模块使用方法与心得体会— int* ,char*等指针类型互转

    https://blog.51cto.com/u_15329836/3413057

    list_test.c

    
    #include 
    
    //extern "C"
    //{
    //  void intList(int numList[]);
    //}
    
    void intList(int numList[])
    {
      int i ;
      for(i= 0 ; i< 10; i++){
        printf("%d %d\n",i,numList[i]);
    
      }
    
      for(i =0; i< 10; i++){
    
         numList[i] = i ;
      }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    gcc -c -fPIC list_test.c
    gcc -shared list_test.o -o list_test.so

    list_test.py

    from ctypes import *
    dllObj = CDLL('./list_test.so')
    
    numList = (c_int * 10)(99,66,55,88,33,22)
    
    dllObj.intList(numList)
    
    for i in numList:
       print(i)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    python3 list_test.py
    运行结果:

    0 99
    1 66
    2 55
    3 88
    4 33
    5 22
    6 0
    7 0
    8 0
    9 0
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Python–ctypes(数据类型详细踩坑指南)

    https://blog.csdn.net/sinat_22510827/article/details/123435081

  • 相关阅读:
    NNDL 实验七 循环神经网络(3)LSTM的记忆能力实验
    【C++】class的设计与使用(三)mutable(可变)和const(不变)
    Python酷库之旅-第三方库openpyxl(20)
    游戏盾是什么,如何保护网络游戏的安全
    正则表达式:整数
    IT行业就业方向如何选择?
    AOSP 编译真机镜像与AVD镜像
    uni-app vue3+ts+vite采坑说明
    kubernetesr进阶--条件化的污点(TaintNodesByCondition)
    Kotlin 协程之取消与异常处理探索之旅(下)
  • 原文地址:https://blog.csdn.net/wowocpp/article/details/126345705