如何使用malloc和free与Python ctypes的? [英] How to use malloc and free with python ctypes?

查看:2438
本文介绍了如何使用malloc和free与Python ctypes的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数在我的C库,比如 runsim()这需要指向结构repdata 为一体的参数,其中结构repdata

I have a function in my C library, say runsim() which takes pointer to struct repdata as one of the arguments, where struct repdata is given by

struct repdata {
    int *var1;
    int *var2;
    int *var3;
    char *var4;
    double *var5;
    double *var6;
    int *var7;
};

在专门使用C,我初始化键入结构repdata 调用函数的变量,

When using C exclusively, I initialize a variable of type struct repdata calling the function,

struct repdata data;
void create_data_container(struct repdata *data, int len_data)
{

    data -> var1 = malloc( sizeof(int) * len_data );
    data -> var2 = malloc( sizeof(int) * len_data );
    data -> var3 = malloc( sizeof(int) * len_data );
    data -> var4 = malloc( sizeof(char) * len_data );
    data -> var5 = malloc( sizeof(double) * len_data);
    data -> var6 = malloc( sizeof(double) * len_data);
    data -> var7 = malloc( sizeof(int) * len_data);
}

然后填写这个结构的模拟收益。我已经写入文件中的数据后,我使用标准的释放内存

and then fill this struct as simulation proceeds. After I have written the data to a file, I free the memory using the standard

free(data.var1);
free(data.var2);
.
.
.
free(data.var7);

我想打电话给在Python使用Python的ctypes的 runsim()功能。为此,我需要一个指针传递给一个变量(即相当于结构repdata 的类型)为一体的 runsim()参数。假设在Python我已经定义的结构repdata 按以下方式等同。

I want to call the runsim() function from Python using Python Ctypes. For this I need to pass a pointer to a variable (that is equivalent to the type of struct repdata) as one of the runsim() arguments. Suppose that in Python I have defined an equivalent of struct repdata in the following manner.

import ctypes as C

class Repdata(C.Structure):
    _fields_ = [
        ("var1", C.POINTER(C.c_int)),
        ("var2", C.POINTER(C.c_int)),
        ("var3", C.POINTER(C.c_int)),
        ("var4", C.POINTER(C.c_char)),
        ("var5", C.POINTER(C.c_double)),
        ("var6", C.POINTER(C.c_double)),
        ("var7", C.POINTER(C.c_int)),
    ]

什么是 create_data_container 相当于上面显示的Python端的功能?我想初始化可被传递至C code和具有用于存储复制数据足够存储器Repdata的一个实例。而且,一旦模拟完成后,如何从Python中释放内存?

What is the equivalent of create_data_container function shown above on the Python side? I want to initialize an instance of Repdata which can be passed to C code and has sufficient memory for storing the replication data. And, once simulation is completed, how do I free the memory from Python?

我使用Ubuntu Linux操作系统12.04。

I am using Ubuntu Linux 12.04.

在此先感谢您的帮助。

推荐答案

您可以使用 ctypes的分配缓冲区,并将它们分配到指针。一旦Python的ctypes的对象没有引用他们将被自动释放。这里有一个简单的例子(与Windows DLL ......没有一台Linux机器方便的,但这个想法是一样的)和Python包装。

You can allocate buffers using ctypes and assign them to the pointers. Once the Python ctypes objects have no references they will be freed automatically. Here's a simple example (with a Windows DLL...don't have a Linux machine handy, but the idea is the same) and a Python wrapper.

<一个href=\"http://docs.python.org/3/library/ctypes.html?highlight=create_string_buffer#ctypes.create_string_buffer\"相对=nofollow> create_string_buffer 分配,可以在Python传递到C可写的缓冲区 ctypes的将编组为一个的char *

您还可以创建 ctypes的类型的语法写数组:

You can also create writable arrays of ctypes types with the syntax:

variable_name = (ctypes_type * length)(initial_values)

x.h

#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

struct example {
    char* data;
    int len;          // of data buffer
    double* doubles;
    int count;        // of doubles
};

DLL_API void func(struct example* p);

x.c

#include <stdio.h>
#define DLL_EXPORTS
#include "x.h"

void func(struct example* p)
{
    int i;
    strcpy_s(p->data,p->len,"hello, world!");
    for(i = 0; i < p->count; i++)
        p->doubles[i] = 1.1 * (i + 1);
}

x.py

import ctypes

class Example(ctypes.Structure):

    _fields_ = [
        ('data',ctypes.POINTER(ctypes.c_char)),
        ('len',ctypes.c_int),
        ('doubles',ctypes.POINTER(ctypes.c_double)),
        ('count',ctypes.c_int)]

    def __init__(self,length,count):
        self.data = ctypes.cast(ctypes.create_string_buffer(length),ctypes.POINTER(ctypes.c_char))
        self.len = length
        self.doubles = (ctypes.c_double * count)()
        self.count = count

    def __repr__(self):
        return 'Example({},[{}])'.format(
            ctypes.string_at(self.data),
            ','.join(str(self.doubles[i]) for i in range(self.count)))

class Dll:

    def __init__(self):
        self.dll = ctypes.CDLL('x')
        self.dll.func.argtypes = [ctypes.POINTER(Example)]
        self.dll.func.restype = None

    def func(self,ex):
        self.dll.func(ctypes.byref(ex))

d = Dll()
e = Example(20,5)
print('before:',e)
d.func(e)
print ('after:',e)

输出

before: Example(b'',[0.0,0.0,0.0,0.0,0.0])
after: Example(b'hello, world!',[1.1,2.2,3.3000000000000003,4.4,5.5])

这篇关于如何使用malloc和free与Python ctypes的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆