Tengo un c-dll al que llamo desde python. La salida del dll es bastante grande y sospecho que esto causa un error
OSError: exception: stack overflow
Estoy bastante seguro de que el problema es el tamaño de la salida (aproximadamente 4x25x720 dobles). Reducir el tamaño de la salida (que no quiero hacer) hace que el error desaparezca.
En C#, puedo solucionar este problema asignando más memoria al subproceso de llamada, es decir,
thread = new Thread(() => calculate(ptr_in, ptr_out), 20000000);
¿Es posible hacer algo similar con ctypes
?
Este NO es el problema publicado aquí Ctypes: OSError:Exception: stack overflow.
EDITAR
Reflexionando sobre el problema, no creo que el problema sea el tamaño de la salida, sino el espacio que necesita el dll real. Es decir c_out inner_out
, definido en ctypes_test.c. De todos modos, el problema sigue siendo el mismo.
En CI definir un dll de pruebadll_ctypes_test
ctypes_testT.h
#pragma once
#define N_ELEMENTS 1000
#define N_ARRAYS 50
typedef struct
{
double var_0;
double var_1;
double var_2;
double var_3;
double var_4;
double var_5;
double var_6;
double var_7;
double var_8;
double var_9;
} element;
typedef struct
{
int n_elements;
element elements[N_ELEMENTS];
} arr;
typedef struct
{
int n_arrays;
arr arrays[N_ARRAYS];
} c_out;
ctypes_test.c
#include "ctypes_testT.h"
__declspec(dllexport) void _stdcall dll_ctypes_test(double in, c_out *out)
{
c_out inner_out;
//Some caluclations on inner_out
//Wrap values of inner arr to out
}
Y el código Python
import ctypes
N_ELEMENTS = 1000
N_ARRAYS = 50
class element(ctypes.Structure):
_fields_ = [('var_0', ctypes.c_double),
('var_1', ctypes.c_double),
('var_2', ctypes.c_double),
('var_3', ctypes.c_double),
('var_4', ctypes.c_double),
('var_5', ctypes.c_double),
('var_6', ctypes.c_double),
('var_7', ctypes.c_double),
('var_8', ctypes.c_double),
('var_9', ctypes.c_double)]
class arr(ctypes.Structure):
_fields_ = [('n_elements', ctypes.c_int),
('elements', element * N_ELEMENTS)]
class c_out(ctypes.Structure):
_fields_ = [('n_arrays', ctypes.c_int),
('arrays', arr * N_ARRAYS)]
dll = ctypes.WinDLL(r'C:\repos\ctypes_test\x64\Debug\ctypes_test.dll')
dll.dll_ctypes_test.argtypes = [ctypes.c_double, ctypes.POINTER(c_out)]
dll.dll_ctypes_test.restype = None
dll.dll_ctypes_test(5, ctypes.byref(c_out()))
Llamar al código de Python produce
Traceback (most recent call last):
File "<ipython-input-15-7c8b287888d0>", line 1, in <module>
dll.dll_ctypes_test(5, c_out())
OSError: exception: access violation writing 0x00000062BA400000
Si cambio N_ARRAYS
de 50
a, digamos, 10
. El error desaparece.
Solución del problema
Listado [Python.Docs]: ctypes: una biblioteca de funciones externas para Python.
Debo decir que no pude reproducir el comportamiento (incluso sin corregir los errores a continuación), usando Python "normal" o IPython. Tal vez haya más en la implementación de dll_ctypes_test de lo que parece.
Asuntos actuales:
A continuación se muestra un ejemplo (una versión modificada de su código).
dll00.h:
#pragma once
#if defined(_WIN32)
# if defined DLL00_EXPORTS
# define DLL00_EXPORT_API __declspec(dllexport)
# else
# define DLL00_EXPORT_API __declspec(dllimport)
# endif
#else
# define DLL00_EXPORT_API
No hay comentarios:
Publicar un comentario