2011-05-05 10 views
8

He leído en esta página que las matrices dinámicas necesitan que la unidad ShareMem funcione correctamente.¿Cómo pasar una matriz dinámica de cadena a una biblioteca dll (DLL y cliente escritos en d7) sin ShareMem Unit?

Sin embargo, me gustaría escribir un archivo DLL abierta para otros idiomas.

Podría alguien decirme cómo puedo declarar la función y sus parámetros a pasar array de cadenas?

no es realmente algo como esto no está permitido sin sharemem?

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

¡Gracias por la ayuda!

+1

@ user740144, No olvide declarar sus funciones/proc exportados como 'stdcall' si desea usarlo el dll con clientes que no sean Delphi. – Johan

+0

@Johan Puede usar 'stdcall' o' cdecl'. 'stdcall' será algo estándar en Windows, pero' cdecl' también podría tener sentido. La convención '__fastcall' no es tan estándar. –

Respuesta

6

una matriz dinámica de cadenas ya es una matriz de PWideChar/PAnsiChar (por WideString or UnicodeString/AnsiString).

Esta matriz dinámica se puede asignar directamente como es, sin copia de la memoria, de la mayoría de las lenguas, como una matriz de PWideChar/PAnsiChar:

De persona que llama:

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

De 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; 

Desde un dll C por ejemplo, puede usar char **argv en lugar de PPAnsiCharArray y void **argv en lugar de PPWideCharArray.

A continuación, puede convertir fácilmente de nuevo la PWideChar/PAnsiChar en el tipo de cadena nativo de la lengua.

Si sólo necesita escribir una DLL de Delphi, puede utilizar

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 incluso

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

Entonces, si lo entiendo, puedo usar sin preocupaciones el código de mi publicación, y recuperar la matriz como usted escribió en un dll? – user740144

+0

¡Gracias por su solución! – user740144

+1

Veo ahora que mi respuesta fue para enviar los datos de otra manera. Pero no estoy interesado en su dependencia de los detalles de implementación de las matrices abiertas. Eso es un poco hacky en mi opinión. –

Cuestiones relacionadas