2012-11-25 155 views
0

我正在玩python ctypes,可能有人可以告訴我一些優雅的方式來處理在C中創建的導出緩衝區mallocpython:使用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 playing_ctypes.so playing_ctypes.c

,然後我用蟒蛇玩:

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是一個buffe r被動態分配,當它被調用時它返回c_void_p(147438576)c_long(147438576)

它依賴於聲明的ctypes導出類型。

當我打電話testlib.ciao()一切正常的話,但如果我想增加,減少或簡單地改變這些任意整數的ctypes的一個價值,我可以覆蓋它以這種方式:

c_numero.value = 89 

由於我們看到它的整數效果非常好。但對於malloched變量c_number_2,屬性.value返回緩衝區的地址(?),如果我想要更改其中的整數值,該怎麼辦?

或者,在其他的世界裏,如何以一種優雅的方式導出一個帶有ctypes的指針並且用他的內容值進行播放。

也許我會用memcpy或者編寫一種python.ctypes處理程序,但是首先寫一些醜陋的硬編碼,我得問你的幫助。

那裏有嗎? :)

回答

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 

這是所有:) 歡呼

0

這絕對是最優雅的方式來做到這一點:

c_numero_2_content = (ctypes.c_long).from_address(c_numero_2.value) 
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的restype跳過投:

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