0

我正在玩一些 python ctypes,可能有人可以告诉我一些优雅的方法来处理用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 playing_ctypes.so playing_ctypes.c

然后我用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

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

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

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

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

c_numero.value = 89

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

或者,在其他世界中,如何使用 ctypes 导出指针并以优雅的方式使用其内容值。

可能我会使用memcpy或编写一种 python.ctypes 处理程序,但是,首先编写一些难看的硬编码,我必须寻求你的帮助。

有吗?:)

4

3 回答 3

2

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

输出:

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

请注意,您可以对 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
于 2012-11-25T20:35:26.000 回答
0

好的,看来我可以在三行代码中做到这一点

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 

就是这样:) 干杯

于 2012-11-25T18:18:07.873 回答
0

这绝对是最优雅的方式:

c_numero_2_content  = (ctypes.c_long).from_address(c_numero_2.value) 
于 2012-11-25T19:04:26.007 回答