3 votes

Comment passer un tableau 2d retourné dans une fonction C à python en utilisant ctypes

J'ai une fonction C qui retourne un tableau 2d (en fait un double**), je veux passer ce double** à python en utilisant ctypes. Il y a des questions à ce sujet mais le tableau est modifié dans la liste des paramètres plutôt que d'utiliser le retour de la fonction. Voici mon code (La fonction C et le wrapper python correspondant)

double** flux_function_2d(double *u, double gamma){

  double **F;
  double p, H;

  F = (double **)malloc(4*sizeof(double *));
  for (int i = 0; i < 4; i++)
    F[i] = (double *)malloc(2*sizeof(double));

  p = (gamma - 1.0) * (u[3] - 0.5 * (u[1]*u[1] + u[2]*u[2]) / u[0]);
  H = u[3] / u[0] + p / u[0];

  F[0][0] = u[1]; F[1][0] = u[1] * u[1] / u[0] + p;
  F[2][0] = u[1] * u[2] / u[0]; F[3][0] = u[1] * H;

  F[0][1] = u[2]; F[1][1] = u[2] * u[1] / u[0];
  F[2][1] = u[2] * u[2] / u[0] + p; F[3][1] = u[2] * H;

  return F;
}

def c_flux_function_2d(u, gamma):
    flux = np.ctypeslib.load_library("libs/flux.so", ".")
    flux.flux_function_2d.argtypes = [POINTER(c_double), c_double]
    flux.flux_function_2d.restype = POINTER(POINTER(c_double))
    F = flux.flux_function_2d(u.ctypes.data_as(POINTER(c_double)),
        c_double(gamma))
    F_arr = np.ctypeslib.as_array(F, shape=(4, 2))
    return F_arr

L'erreur se produit à F_arr = np.ctypeslib.as_array(F, shape=(4, 2)) ce qui signifie que numpy ne peut pas analyser le pointeur d'un pointeur dans ctypes.

Merci d'avance !

2voto

user2357112 Points 37737

Si vous avait en fait un tableau 2D, vous pouvez appeler numpy.ctypeslib.as_array mais vous Ne le fais pas. .

Vous avez un pointeur sur le premier élément d'un tableau de pointeurs sur les premiers éléments d'autres tableaux. C'est une chose complètement différente d'un tableau 2D, qui se trouve être indexable avec la même syntaxe en C.

La disposition de la mémoire de ce que vous avez est complètement incompatible avec NumPy. Les tableaux NumPy ont un seul tampon mémoire avec des informations de forme et de stride indiquant jusqu'où vous pouvez aller dans chaque dimension et combien d'octets vous devez parcourir pour faire un pas dans chaque dimension.

Pour un tableau C-contigu (le cas le plus courant), la disposition de la mémoire du tampon d'un tableau MxN est la même que pour un tableau C whatevertype[M][N] . En revanche, les sous-réseaux de votre structure de données sont dispersés dans des emplacements mémoire arbitraires, sans qu'il y ait de stride dans la première dimension.

Vous devrez mettre vos données dans un format avec lequel NumPy peut travailler. Il existe plusieurs façons de le faire, notamment en allouant et en travaillant avec un tampon contigu dans la fonction C, ou en créant un fichier de type numpy.empty([4, 2]) et copier les données dans cette dernière avec une boucle imbriquée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X