zoukankan      html  css  js  c++  java
  • Python使用ctypes访问C代码

    工具:CodeBlocks

    新建一个分享库工程( Shared library ),随便编写一个C代码的函数

    // test.c
    
    #include <stdio.h>
    
    int fib(int n)
    {
        if( n == 0 || n == 1)
        {
            return 1;
        }
        else
        {
            return fib(n-1) + fib(n-2);
        }
    }


    编译,在bin/Debug/目录中生成libtest.dll动态链接库文件,该文件可以通过ctypes模块进行访问使用,在该文件目录下新建一个test.py文件

    # test.py
    
    import ctypes
    import os
    
    _file_path = os.path.join(os.path.dirname(__file__), 'libtest.dll')
    _mod = ctypes.cdll.LoadLibrary(_file_path)   #加载动态库文件,返回一个类对象 <class 'ctypes.CDLL'>
    
    
    # int fib(int n)
    fib = _mod.fib               #获取类方法
    fib.argtypes = (ctype_int,)  #配置参数类型(tuple)
    fib.restype = ctypes_int     #配置返回值类型
    
    
    #现在可以直接使用fib函数了
    for i in range(10):
        print( fib(i), end=' ' )


    C函数的指针作为参数情况

    // 参数有指针的函数
    int divide(int a, int b, int *remainder) {
        int quot = a / b;
        *remainder = a % b;
        return quot;
    }
    

    # 相应的处理办法
    
    # int divide(int, int, int *)
    _divide = _mod.divide
    _divide.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int))   
    _divide.restype = ctypes.c_int
    
    def divide(x, y):
      rem = ctypes.c_int()
      quot = _divide(x, y, rem)
      return quot,rem.value

    C函数的数组作参数的情况 

    double avg(double *a, int n) {
        int i;
        double total = 0.0;
        for (i = 0; i < n; i++) {
            total += a[i];
        }
        return total / n;
    # 对于C中的数组,Python中没有固定的对应类型,所以要分类处理:
    # Define a special type for the 'double *' argument class DoubleArrayType: def from_param(self, param): #对传进来的参数进行分发 typename = type(param).__name__ if hasattr(self, 'from_' + typename): return getattr(self, 'from_' + typename)(param) elif isinstance(param, ctypes.Array): return param else: raise TypeError("Can't convert %s" % typename) # Cast from array.array objects def from_array(self, param): if param.typecode != 'd': raise TypeError('must be an array of doubles') ptr, _ = param.buffer_info() return ctypes.cast(ptr, ctypes.POINTER(ctypes.c_double)) # Cast from lists/tuples def from_list(self, param): val = ((ctypes.c_double)*len(param))(*param) return val from_tuple = from_list # Cast from a numpy array def from_ndarray(self, param): return param.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) DoubleArray = DoubleArrayType() _avg = _mod.avg _avg.argtypes = (DoubleArray, ctypes.c_int) _avg.restype = ctypes.c_double def avg(values): return _avg(values, len(values))
    KEEP LEARNING!
  • 相关阅读:
    [SDOI 2009] 晨跑
    [ZJOI 2009] 假期的宿舍
    [BZOJ 2006] 狼抓兔子
    [BZOJ 1691] 挑剔的美食家
    [HNOI 2015] 菜肴制作
    [Codeforces 489E] Nastya and King-Shamans
    sum(sum(abs(y))) 中 sum(sum())什么意思?
    matlab 函数 bwarea
    系统启动挂载根文件系统时Kernel panic
    rmmod: chdir(/lib/modules): No such file or directory
  • 原文地址:https://www.cnblogs.com/roronoa-sqd/p/5446524.html
Copyright © 2011-2022 走看看