2011-05-05 4 views
8

Ho letto su questa pagina che gli array dinamici hanno bisogno che l'unità ShareMem funzioni correttamente.Come passare array dinamici di stringhe in una libreria dll (dll e client scritti in d7) senza ShareMem Unit?

Tuttavia mi piacerebbe scrivere una DLL aperta per altre lingue.

Qualcuno potrebbe dirmi come posso dichiarare la funzione ei suoi parametri per passare l'array di String?

Non è davvero qualcosa di simile non consentito senza ShareMem?

var 
    templates : array of WideString; 
begin 
    SetLength(templates, 2); 
    templates[0] := 'template1'; 
    templates[1] := 'template2'; 
end 
DLLFunction(@templates[0]); 

Grazie per l'aiuto!

+1

@ user740144, Non dimenticare di dichiarare le funzioni/procs esportate come 'stdcall' se vuoi usarlo la DLL con i client non-delphi. – Johan

+0

@Johan Puoi usare 'stdcall' o' cdecl'. 'stdcall' sarà un po 'standard in Windows, ma' cdecl' potrebbe anche avere un senso. La convenzione '__fastcall' non è così standard. –

risposta

6

Una matrice dinamica di stringhe è già una serie di PWideChar/PAnsiChar (per WideString or UnicodeString/AnsiString).

Questo array dinamico può essere mappato direttamente come è, senza copia della memoria, da molti linguaggi, come un array di PWideChar/PAnsiChar:

Da chiamante:

DLLFunction(length(templates),pointer(templates)); 

Da dll:

type 
    TPAnsiCharArray = array[0..MaxInt div SizeOf(PAnsiChar)-1] of PAnsiChar; 
    PPAnsiCharArray = ^TPAnsiCharArray; 
    TPWideCharArray = array[0..MaxInt div SizeOf(PWideChar)-1] of PWideChar; 
    PPWideCharArray = ^TPWideCharArray; 

procedure DLLFunction(argc: integer; argv: PPWideCharArray); 
var i: integer; 
begin 
    for i := 0 to argc-1 do 
    writeln(argv[i]); 
end; 

Da una DLL C, ad esempio, è possibile utilizzare char **argv anziché PPAnsiCharArray e void **argv anziché PPWideCharArray.

Quindi è possibile convertire facilmente lo PWideChar/PAnsiChar nel tipo di stringa nativo della lingua.

Se è necessario solo per scrivere un dll Delphi, è possibile utilizzare

type 
    TAnsiStringArray = array[0..MaxInt div SizeOf(AnsiString)-1] of AnsiString; 
    PAnsiStringArray = ^TAnsiStringArray; 
    TWideStringArray = array[0..MaxInt div SizeOf(WideString)-1] of WideString; 
    PWideStringArray = ^TWideStringArray; 

procedure DLLFunction(argc: integer; argv: PWideStringArray); 
var i: integer; 
begin 
    for i := 0 to argc-1 do 
    writeln(argv[i]); 
end; 

o anche

DLLFunction(templates); 

procedure DLLFunction(const templates: array of WideString); 
var i: integer; 
begin 
    for i := 0 to high(templates) do 
    writeln(templates[i]); 
end; 
+0

Quindi, se ho capito, posso usare senza problemi il codice dal mio post e recuperare l'array proprio come hai scritto in una dll? – user740144

+0

Grazie per la soluzione! – user740144

+1

Ora vedo che la mia risposta era per l'invio dei dati nell'altro modo. Ma non sono propenso a fare affidamento sui dettagli di implementazione degli open array. Questo è un po 'hacky a mio avviso. –