2010-02-16 3 views
5

Próbujemy przekazać ciąg z natywnego programu Delphi do biblioteki DLL Delphi Prism. Nie mamy problemu z przekazywaniem liczb całkowitych, ale łańcuchy są niedopasowane w bibliotece DLL. Widzieliśmy Robert Love's code snippet w odpowiedzi na inne pytanie, ale nie ma kodu dla natywnego programu Delphi.Jak mogę przekazać ciąg znaków Delphi do biblioteki DLL Prism?

Jak przekazać ciągi z Delphi do biblioteki DLL Delphi Prism?

+3

To jest społeczność, więc nie powinieneś adresować pojedynczej osoby w twoim pytaniu. Jeśli chcesz to zrobić, napisz komentarz do jego odpowiedzi. Jeśli napiszesz pytanie (które w tym przypadku jest lepsze), postaraj się sformułować je jak najbardziej ogólne. – jpfollenius

+0

Uzgodnione. Robert Giesecke odpowiedział na to lepiej niż ja mogłem. –

Odpowiedz

1

Struny w Delphi Win32 są zarządzane inaczej niż łańcuchy w .Net, więc nie można przekazać łańcucha .Net do Delphi Win32 ani na odwrót.

Aby wymienić wartości łańcuchów, lepiej użyć typu PChar obsługiwanego przez oba kompilatory. W ten sam sposób wysyłane są wartości ciągów do funkcji Windows API.

Pozdrawiam

P.S. NIE JESTEM Robertem ;-)

+0

Przepraszamy, to powinien być komunikat do autora wspomnianego fragmentu kodu. Kliknął nieprawidłowy przycisk. Ale tak, jak to działa, aby korzystać z PChar. Pryzmat Delphi nie ma typu PChar. jeśli używam pchar w natywnym delphi i string w pryzmacie, otrzymuję pierwszy znak prawy. Ale tylko jeden znak. Jak to naprawić? –

+1

Nie martw się, Marcus. Nie masz jeszcze wystarczającej liczby punktów reputacji, więc i tak nie byłbyś w stanie opublikować pochwały na czyimś pytaniu. To uzasadnione pytanie. Zmieniliśmy to dla Ciebie, więc nie wygląda na to, że próbujesz wysłać bezpośrednią wiadomość, której nie obsługuje Stack Overflow. –

+0

PChar jest po prostu wskaźnikiem do znaku, aby wysłać ciąg znaków, taki jak ten, który trzeba najpierw wskazać na pierwszy znak, a drugi, określić długość danych ciągu, aby drugi koniec mógł odczytać dane z punktu początkowego do długość struny. Jeśli twoja funkcja DLL zwraca jakąkolwiek wartość ciągu, to drugi koniec powinien zapewnić pamięć i wysłać jej adres początkowy i długość do funkcji, aby twoja funkcja mogła zapisywać dane wyjściowe do tego obszaru pamięci. – vcldeveloper

8

Najlepszym sposobem byłoby użycie WideString.

Z kilku powodów.

  • Jest Unicode i pracuje przed D2009
  • To pamięć jest zarządzana Ole32.dll, więc nie ma zależność obu menedżera pamięci Delphi lub CLR GC.
  • Nie masz do czynienia bezpośrednio z wskaźniki

W Oxygene, można napisać tak:

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” opowiada CLR sposobu organizowania ciągów iz powrotem. Bez tego ciągi są przekazywane jako Ansi (PAnsiChar), co prawdopodobnie jest zadaniem, które chciałbyś zrobić.

To jak go używać z 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. 

Również nigdy typy użytku, które nie są wyraźnie zdefiniowane, dla interfejsów zewnętrznych. Nie można używać PChar do importowania lub eksportowania bibliotek DLL. Bo jeśli to zrobisz, natkniesz się na wyjątki, gdy skompilujesz je z D7 lub D2009 (w zależności od oryginalnego systemu deweloperskiego).