Python处理带ctypes的c malloc变量

2024-06-09 13:49:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我在玩python ctypes,也许有人可以告诉我一些优雅的方法来处理用C创建的带有malloc的导出缓冲区。在

所以,这是一个非常愚蠢的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);

}

我编译它: gcc-shared-o播放_ctypes.so播放\u ctypes.c

然后我用python玩:

^{pr2}$

众所周知,c_numero是一个整数,当从python终端调用它时,它返回c_long(54)

同时,c_numero_2是一个动态分配的缓冲区,当它被调用时,它返回c_void_p(147438576)或{}

它取决于声明的ctypes导出类型。在

当我调用testlib.ciao()时,一切正常,但是如果我想增加、减少或只是任意更改这些ctypes整数之一的值,我可以用这种方式覆盖它:

c_numero.value = 89

正如我们看到的整数,它工作得很好。但是对于malloched变量c_number_2,属性.value返回buffer(?)的地址如果我想改变它的值,整数怎么办?在

或者,在另一个世界里,如何导出一个带有ctypes的指针并以优雅的方式发挥其内容价值呢。在

可能我会使用memcpy或者写一个python.ctypes但是,首先写一些难看的硬编码,我得请你帮忙。在

有吗?:)


Tags: include整数ctypesint缓冲区creadynciao
3条回答

您可以像在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])

输出:

^{pr2}$

请注意,您可以谎称malloc的重新输入以跳过演员阵容:

dll.malloc.restype = POINTER(c_int)

您的全局变量可以这样访问:

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

这绝对是最优雅的方法:

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

好吧,看来我用三行代码就能搞定

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 

仅此而已:) 干杯

相关问题 更多 >