简体   繁体   English

python:使用ctypes处理c malloc变量

[英]python: handling c malloc variables with ctypes

I'm playing a bit with python ctypes, probably someone could tell me some elegant way to handle an exported buffer created in C with a malloc . 我打了一下使用python的ctypes,也许有人能告诉我一些优雅的方式来处理下,用创建的导出缓冲区malloc

So, it's a very stupid c code that could explain what I'm looking for. 所以,这是一个非常愚蠢的c代码,可以解释我在寻找什么。

#include <stdio.h>
#include <stdlib.h>

char * stringa;
int numero = 0;
int * numero_2;

void crea_variabili_dyn() {

    if ( numero_2 == NULL) {
        numero_2 = malloc(1 * sizeof(int));
        *numero_2 = 2;        
        }

    }


void incrementa() {

    numero += 1;
    *numero_2 += 11;
    }


void ciao() {

    crea_variabili_dyn();
    stringa = "cane.huu";
    incrementa();
    printf("%d\n", numero);
    printf("%d\n", *numero_2);    
    printf("%s\n", stringa);
    incrementa();
    printf("%d\n", numero);
    printf("%d\n", *numero_2);    
    printf("%s\n", stringa);
}



void main (void) {

    //printf("%d\n", numero);
    ciao();
    //printf("%d\n", numero);

}

I compile it: gcc -shared -o playing_ctypes.so playing_ctypes.c 我编译它:gcc -shared -o playing_ctypes.so playing_ctypes.c

and then I play it with python: 然后我用python播放它:

import ctypes

testlib = ctypes.CDLL('/home/gnommaro/Dev/C/playing_ctypes.so')

c_numero = ctypes.c_int.in_dll(testlib, "numero")
c_numero_2 = ctypes.c_int.in_dll(testlib, "numero_2")

c_numero
c_numero_2

testlib.ciao()

c_numero
c_numero_2

As used to know c_numero is a integer and when called from python terminal it returns c_long(54) 用来知道c_numero是一个整数,当从python终端调用它时返回c_long(54)

Meanwhile c_numero_2 is a buffer allocated dynamically and when it's called it returns c_void_p(147438576) or c_long(147438576) 同时c_numero_2是动态分配的缓冲区,当它被调用时返回c_void_p(147438576)c_long(147438576)

It depend byt the declared ctypes export type. 它取决于声明的ctypes导出类型。

When I call testlib.ciao() everything goes ok, but if I'd like to increment, decrement or simply change arbitrarily the value of one of these ctypes integers I can override it in this way: 当我调用testlib.ciao()一切正常,但是如果我想增加,减少或者只是任意改变其中一个ctypes整数的值,我可以用这种方式覆盖它:

c_numero.value = 89

As we Seen for integer it works very well. 正如我们看到整数一样,它的效果非常好。 But for the malloched variable c_number_2 , the attribute .value returns me the address of buffer (?) and How could do if I'd like to change the value, the integer, in it ? 但是对于malloched变量c_number_2 ,属性.value返回缓冲区的地址(?),如果我想更改其中的值,整数怎么办呢?

Or, in other worlds, how could export a pointer with ctypes and playing with his content value in a elegant way. 或者,在其他世界中,如何使用ctypes导出指针并以优雅的方式播放其内容值。

Probably I'd use a memcpy or write a sort of python.ctypes handler but, first of write some ugly hardcoding, I have to ask your help. 可能我会使用memcpy或写一种python.ctypes处理程序,但是,首先写一些丑陋的硬编码,我必须请求你的帮助。

Is any there ? 有吗? :) :)

You can index ctypes pointers just like in C, but don't write past the end of the buffer, just like in C. 您可以像在C中一样索引ctypes指针,但不要写入缓冲区的末尾,就像在C中一样。

from ctypes import *

dll = CDLL('msvcrt')
dll.malloc.restype = c_void_p
n = dll.malloc(5 * sizeof(c_int))
n = cast(n,POINTER(c_int))
for i in range(5):
    print('uninitialized value',n[i])
    n[i] = i
    print('new value',n[i])

Output: 输出:

uninitialized value 6815752
new value 0
uninitialized value 0
new value 1
uninitialized value 6128720
new value 2
uninitialized value 0
new value 3
uninitialized value 0
new value 4

Note you can lie about malloc's restype to skip the cast: 请注意,您可以使用malloc的restype来跳过演员:

dll.malloc.restype = POINTER(c_int)

Your global variable can be accessed like so: 您可以像这样访问您的全局变量:

c_numero_2 = POINTER(c_int).in_dll(testlib, "numero_2")
c_numero_2[0] = 1
c_numero_2[1] = 2

Ok, it seems that in three line of code I could do the trick 好吧,似乎在三行代码中我可以做到这一点

c_long_p = ctypes.POINTER(ctypes.c_long)
c_numero_2_ptr = ctypes.cast(c_numero_2.value, c_long_p)
c_numero_2_ptr.content 

that's all :) cheers 这就是:)干杯

这绝对是最优雅的方式:

c_numero_2_content  = (ctypes.c_long).from_address(c_numero_2.value) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM