2010-02-16 14 views
5

Intentamos pasar una cadena desde un programa nativo de Delphi a una DLL de Delphi Prism. No tenemos problemas para pasar enteros, pero las cadenas no coinciden en la DLL. Vimos Robert Love's code snippet en respuesta a otra pregunta, pero no hay ningún código para el programa nativo Delphi.¿Cómo puedo pasar una cadena Delphi a una DLL Prism?

¿Cómo podemos pasar cadenas de Delphi a una DLL de Delphi Prism?

+3

Esta es una comunidad, por lo que no debe dirigirse a una sola persona en su pregunta. Si quieres hacer eso, escribe un comentario en su respuesta. Si escribe una pregunta (que es mejor en este caso), trate de formularla de la manera más general posible. – jpfollenius

+0

De acuerdo. Robert Giesecke respondió esto mejor de lo que podría haberlo hecho. –

Respuesta

1

Las cadenas en Delphi Win32 se manejan de forma diferente a las cadenas en .Net, por lo que no se puede pasar una cadena .Net a Delphi Win32 o viceversa.

Para intercambiar valores de cadenas, es mejor usar PChar que es compatible con ambos compiladores. Es lo mismo que envía valores de cadena a las funciones de la API de Windows.

Saludos

P. S. NO soy Robert ;-)

+0

Disculpe, esto debería ser un mensaje para el autor del fragmento de código mencionado anteriormente. Haz clic en el botón equivocado. Pero de todos modos, ¿cómo funciona usar PChar. El prisma Delphi no tiene un tipo PChar. si uso pchar en delphi nativo y cadena en prisma, obtengo el primer carácter a la derecha. Pero solo un char. ¿Cómo solucionar esto? –

+1

No se preocupe, Marcus. Aún no tienes suficientes puntos de reputación, por lo que de todos modos no hubieras podido enviar un comentario a la pregunta de otra persona. Es una pregunta legítima. Lo he editado para que no parezca que estás tratando de enviar un mensaje directo, que Stack Overflow no admite. –

+0

PChar es simplemente un puntero a un personaje, para enviar una cadena como esa, primero debe señalar al primer carácter, y segundo, especificar la longitud de los datos de cadena, para que el otro extremo pueda leer datos desde el punto de inicio hasta la longitud de la cuerda. Si su función DLL está devolviendo cualquier valor de cadena, el otro extremo debe proporcionar un espacio de memoria y enviar su dirección inicial y su longitud a su función para que su función pueda escribir los datos de salida en ese espacio de memoria. – vcldeveloper

8

La mejor manera sería usar WideString.

Por varias razones.

  • Es Unicode y funciona antes D2009
  • Es la memoria se gestiona de ole32.dll, por lo que hay dependencia de cualquiera administrador de memoria de Delphi o el CLR GC.
  • Usted no tiene que tratar directamente con los punteros

En Oxygene, podría escribir que de este modo:

type 
    Sample = static class 
    private 
    [UnmanagedExport] 
    method StringTest([MarshalAs(UnmanagedType.BStr)]input : String; 
         [MarshalAs(UnmanagedType.BStr)]out output : String); 
    end; 

implementation 

method Sample.StringTest(input : String; out output : String); 
begin 
    output := input + "ä ~ î 暗"; 
end; 

"MarshalAs" cuenta la CLR cómo calcular cadenas de ida y vuelta. Sin él, las cadenas se pasan como Ansi (PAnsiChar), que es probablemente NO lo que desea hacer.

Esto es cómo usarlo desde Delphi:

procedure StringTest(const input : WideString; out output : WideString); 
    stdcall; external 'OxygeneLib'; 

var 
    input, output : WideString; 
begin 
    input := 'A b c'; 
    StringTest(input, output); 
    Writeln(output); 
end. 

Además, nunca tipos de uso, que no están claramente definidos, para las interfaces externas. No debe usar PChar para las importaciones o exportaciones de DLL. Porque si lo hace, se encontrará con excepciones cuando lo compile con D7 o D2009 (dependiendo de cuál fue el sistema de desarrollo original)

Cuestiones relacionadas