c_int python pointers dll char ctypes

python - c_int()



¿Cómo pasar el puntero en ctypes? (2)

No sé mucho sobre los tipos, hace poco empecé a trabajar con él.

Tengo una función simple en C-like dll que devuelve un puntero a la cadena generada dinámicamente.
Está funcionando bien, pero, como he asignado manualmente la memoria para la cadena, debería liberarla después de su uso.

Tengo algo como esto:

extern "C" char* DLL_EXPORT func(const char* str1, const char* str2) { return getSomeString(str1, str2); } // Goal is to call this function correctly from Python. extern "C" void DLL_EXPORT freeMem(void *mem) { if(mem!=NULL) delete mem; }

Pero no tengo ni idea, ¿cómo puedo pasar el puntero recibido para su eliminación en Python?


Estás en el camino correcto.

// TestDLL.cpp #include <string.h> // strcpy extern "C" __declspec(dllexport) char* stringdup(const char* str) { char* p = new char[strlen(str)+1]; strcpy(p,str); return p; } // if you have no good reason to use void*, use the type // you''ve allocated. while it usually works for built-in // types, it wouldn''t work for classes (it wouldn''t call // the destructor) extern "C" __declspec(dllexport) void stringfree(char* ptr) { // you don''t need to check for 0 before you delete it, // but if you allocate with new[], free with delete[] ! delete [] ptr; }

Y en python:

# Test.py import ctypes lib = ctypes.cdll.TestDLL # this creates a c-style char pointer, initialized with a string whose # memory is managed by PYTHON! do not attempt to free it through the DLL! cstr = ctypes.c_char_p("hello ctypes") # call the dll function that returns a char pointer # whose memory is managed by the DLL. p = lib.stringdup(cstr) # p is just an integer containing the memory address of the # char array. therefore, this just prints the address: print p # this prints the actual string print ctypes.c_char_p(p).value # free the memory through the DLL lib.stringfree(p)


Normalmente, cada función que use en ctypes debe tener sus argumentos y tipo de declaración declarados para que Python pueda verificar el número y tipo correcto de argumentos y convertir los argumentos del objeto Python en los objetos de datos C correctos. Desafortunadamente en este caso, el valor de retorno normal para func sería c_char_p , pero ctypes intenta ser útil y convierte un valor de retorno c_char_p en una cadena de Python, perdiendo acceso al valor del puntero en C sin formato. En su lugar, puede declarar el tipo de devolución como c_void_p y usar cast para recuperar el valor de cadena, que deja el valor de retorno como un objeto c_char_p .

Aquí hay un ejemplo (Python 3):

import ctypes func = ctypes.cdll.TestDLL.func func.argtypes = [ctypes.c_char_p,ctypes.c_char_p] func.restype = ctypes.c_void_p freeMem = ctypes.cdll.TestDLL.freeMem freeMem.argtypes = [ctypes.c_void_p] freeMem.restype = None s = func(b''abcdef'',b''ghijkl'') s = ctypes.cast(s,ctypes.c_char_p) print(s.value) freeMem(s)