Appeler une fonction C de Julia et passer un tableau 2D en tant que pointeur de pointeurs en tant qu’argument

L’arrière-plan

J’essaie d’utiliser la fonction ccall Julia pour utiliser le code écrit en C. Je sais comment passer un tableau en tant qu’argument à une fonction qui attend int *arg . Par exemple, essayer d’utiliser cette fonction C

 void sum_one(int *arr, int len) { for (int i=0; i<len; i++){ arr[i]++; } } 

ce code Julia fonctionne

 x = collect(Cint, 1:5) ccall((:sum_one, "/path/to/mylib.so"), Void, (Ptr{Cint}, Cint), x, 5) 

Le problème

Cela ne semble pas être aussi simple avec les fonctions C qui s’attendent à ce qu’un pointeur sur un pointeur ( int **arg ) soit utilisé en tant que masortingce à 2 dimensions. Dis celui-ci

 void fill_masortingx(int **arr, int row, int col) { for (int i=0; i<row; i++){ for (int j=0; j<col; j++){ arr[i][j] = arr[i][j] + i + j*10; } } } 

Ici, je devais créer un tableau de tableaux pour que le code C l’accepte:

 xx = [zeros(Cint, 5) for i in 1:6] ccall((:fill_masortingx, "/path/to/mylib.so"), Void, (Ptr{Ptr{Cint}}, Cint, Cint), xx, 6,5) 

Mais cette structure n’est pas très pratique du côté de Julia.

Questions)

  • Existe-t-il un autre moyen de passer une masortingce à 2 dimensions à une fonction C qui attend un argument de type int **arg ?
  • Si non, comment pouvez-vous transformer un tableau à deux dimensions déjà existant de Julia en tableau de structure de tableaux en C?
  • et l’inverse?

    Je vais essayer de répondre à vos questions une à une:

    Existe-t-il un autre moyen de passer une masortingce à 2 dimensions à une fonction C qui attend un argument de type int ** arg?

    Oui. Vous devez append une méthode à la fonction cconvert de julia pour cconvert effectuer la conversion de Masortingx{Cint} en Ptr{Ptr{Cint}} . Donc vous définissez:

     Base.cconvert(::Type{Ptr{Ptr{Cint}}},xx2::Masortingx{Cint})=Ref{Ptr{Cint}}([Ref(xx2,i) for i=1:size(xx2,1):length(xx2)]) 

    (voir la question suivante pour des explications) et peut ensuite transmettre directement votre masortingce à ccall:

     xx2=zeros(Cint,5,6) ccall((:fill_masortingx, "mylib.so"),Void, (Ptr{Ptr{Cint}}, Cint, Cint), xx2, 6,5) 

    Cependant, je suggérerais d’être très conservateur dans les méthodes cconvert que vous écrasez, car un autre code julia pourrait s’attendre au comportement initial.

    Si non, comment pouvez-vous transformer un tableau à deux dimensions déjà existant de Julia en tableau de structure de tableaux en C?

    Ce qui suit devrait fonctionner: Vous générez un tableau de pointeurs sur chaque colonne de votre masortingce, donc dans julia-0.4:

     xx2=zeros(Cint,5,6) refAr=[Ref(xx2,i) for i=1:size(xx2,1):length(xx2)] ccall((:fill_masortingx, "mylib.so"),Void, (Ptr{Ptr{Cint}}, Cint, Cint), refAr, 6,5) 

    Maintenant, la masortingce xx2 est remplie par la fonction C. Notez que dans julia v0.3 vous devez remplacer Ref(xx2,i) par un pointer(xx2,i)

    et l’inverse?

    Je ne pense pas que ce soit généralement possible. Pour construire un tableau julia 2D, les données doivent être dans un bloc de mémoire contigu. Si vous êtes VRAIMENT confiant, c’est le cas que vous pouvez faire:

     p=pointer(refAr) # This is a Ptr{Ptr{Cint}} representing the int** aa=pointer_to_array(p,6,false) bb=pointer_to_array(aa[1],(5,6),false) 

    Ce qui retourne la masortingce d’origine. Ici, le dernier argument de pointer_to_array détermine si Julia prend la propriété du tableau et que les données doivent être libérées par le contrôleur de Julia.

    Je ne suis pas fan de Julia, mais C vous permet définitivement de faire passer des tableaux multidimensionnels:

     void fill_masortingx(int row, int col, int (*arr)[col]) { for (int i=0; i 

    Le fait est qu’aucun tableau de pointeurs n’est impliqué, l’expression arr[i][j] sera évaluée en tant arr[i*col + j] en vertu du type de pointeur de tableau utilisé pour déclarer arr . Les données sont simplement contiguës en mémoire.

    Maintenant, je ne sais pas si Julia vous permet d’interfacer avec une fonction C qui prend un argument de pointeur de tableau comme celui-ci, mais vous pouvez essayer de le savoir. Il peut également être nécessaire d’échanger les index de tableau, selon que Julia stocke ses masortingces dans l’ordre des colonnes ou des lignes. Dans les deux cas, il devrait être facile de le découvrir en essayant.