Dll Delphi-to-C: Passage de tableaux

J’utilise Delphi pour charger une dll (créée dans Delphi XE-3) à des fins d’interfaçage avec du code C. Mon problème est de savoir pourquoi mes tableaux ne sont pas passés aux fonctions c – ce sont les seuls à ne pas le faire. Le fichier Delphi (simplifié) ressemble à ceci:

program CallcCode uses SysUtils, Windows, DLLUnit in 'DLLUnit.pas'; // Header conversion var DLLHandle: cardinal; n: Integer; A: TArray; result1: Integer; begin // Initialize each Array SetLength(A,n); A[0] = ...; // Load the DLL (and confirm its loaded) DLLhandle := LoadLibrary('dllname.dll'); if DLLhandle  0 then begin result1 := dll_func1(n,A); // A and B are not passed correctly end FreeLibrary(DLLHandle); end. 

J’ai réussi à “tracer dans” dll_func1 la première fois, en entrant dans DLLUnit, qui a:

 const nameofDLL = 'dllname'; function dll_func1(n: Integer; A: TArray): Integer; cdecl; external nameofDLL; 

“Trace-into” à nouveau, j’arrive au fichier c, qui a toujours les valeurs n et DLLdefs correctes, mais A (sous l’en-tête “Variables locales”) est devenu:

 [-] A :(Aplha-Numeric) ..[0] 0 (0x00000000) 

Je sais que j’accède au moins correctement à la DLL (heureusement), car les autres appels de fonction fonctionnent normalement et je suis en mesure de localiser le fichier dll_func1.c sans problème. J’ai essayé de changer la fonction pour

 function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL; ... result1 := dll_func1(n,PInteger(A)) 

ou

 function dll_func1(n: Integer; A: PInteger): Integer; cdecl; external nameofDLL; ... result1 := dll_func1(n,@A[0]) 

(en utilisant à la fois TArray et array of Integer ou A) mais il n’ya pas de changement, ce qui me laisse croire que cela est lié à un problème que je ne vois pas. Le tout est compilé et exécuté, mais result1 est incorrect à cause des échecs de TArray. Des idées sur ce qui ne va pas?

EDIT La fonction en C comme:

 int dll_func1(int n, int A []) 

Votre question contient deux déclarations Delphi pour la fonction externe. L’un d’eux utilise TArray tant que paramètre. C’est complètement faux. Ne fais pas ça. Vous ne pouvez pas utiliser un tableau dynamic Delphi en tant que type interop. La raison en est que TArray est un type géré complexe qui ne peut être créé et utilisé que par du code Delphi.

Vous devez faire ce que je fais ci-dessous, et comme je l’ai expliqué dans ma réponse à votre question précédente, et déclarer le paramètre array comme pointeur sur le type d’élément. Par exemple, PInteger , PDouble , etc.

Il y a beaucoup de confusion ici et une complexité inutile. Ce dont vous avez besoin, c’est l’exemple le plus simple possible qui montre comment passer un tableau de votre code Delphi au code C.

Voici est.

Code C

 //testarray.c void printDouble(double d); // linker will resolve this from the Delphi code void test(double *arr, int count) { int i; for (i=0; i 

Code Delphi

 program DelphiToC; {$APPTYPE CONSOLE} uses Crtl; procedure _printDouble(d: Double); cdecl; begin Writeln(d); end; procedure test(arr: PDouble; count: Integer); cdecl; external name '_test'; {$L testarray.obj} var arr: TArray; begin arr := TArray.Create(1.0, 2.0, 3.0, 42.0, 666.0); test(PDouble(arr), Length(arr)); Readln; end. 

Comstackz le code C en utilisant, par exemple, le compilateur Borland C comme ceci:

 bcc32 -c testarray.c

Et le résultat est:

  1.00000000000000E + 0000
  2.00000000000000E + 0000
  3.00000000000000E + 0000
  4.20000000000000E + 0001
  6.66000000000000E + 0002

Notez que je me suis lié au code C de manière statique parce que c'était plus facile pour moi. Rien ne change beaucoup si vous mettez le code C dans une DLL.

La conclusion est que le code que je vous ai donné dans ma réponse à votre précédente, et que je répète ici, est correct. Cette approche réussit à passer un tableau du code Delphi au code C. Il semble que vos diagnostics et le débogage soient en erreur.

Vous inspectez seulement A[0] , il n’est donc pas surprenant que vous ne voyiez qu’une seule valeur. Si seulement vous regardiez A[1] , A[2] , ..., A[n-1] vous verriez que toutes les valeurs sont passées correctement. Ou peut-être que votre débogage a été effectué sur la déclaration erronée de la fonction externe qui utilisait TArray tant que paramètre.