Restituzione di una stringa da una DLL C # con esportazioni non gestite allo script di installazione Inno

Ho una DLL C # che espone una funzione utilizzando Esportazioni non gestite che viene chiamata direttamente da uno script Pascal Inno Setup. Questa funzione deve restituire una stringa in Inno Setup. La mia domanda è come posso realizzare questo?
Il mio metodo preferito è passare un buffer da Inno Setup alla funzione C # che restituirà la stringa all’interno di questo buffer. Ho trovato questo codice:

Funzione C #:

[DllExport("Test", CallingConvention = CallingConvention.StdCall)] static int Test([Out, MarshalAs(UnmanagedType.LPWStr)] out string strout) { strout = "teststr"; return strout.Length; } 

Script di installazione Inno:

 function Test(var res: String):Integer; external '[email protected]:testdll.dll stdcall'; procedure test1; var Res: String; l: Integer; begin SetLength(Res,256); l := Test(Res); { Uncommenting the following line causes an exception } { SetLength(Res,l); } Log('"Res"'); end; 

Quando eseguo questo codice la variabile Res è vuota (vedo “” nel registro)

Come posso restituire una stringa da questa DLL?

Si noti che sto usando la versione Unicode di Inno Setup. Inoltre, non desidero utilizzare COM per chiamare questa funzione né allocare un buffer nella DLL e restituirlo a Inno Setup.

Ti suggerirei di usare il tipo BSTR , che è usato per essere un tipo di dati per le chiamate alle funzioni di interoperabilità. Sul lato C # dovresti eseguire il marshalling della tua stringa come tipo UnmanagedType.BStr e sul lato Inno Setup dovresti usare WideString , che è compatibile con il tipo BSTR . Quindi il tuo codice cambierebbe in questo modo (vedi anche il capitolo di Marshalling sample dei documenti Unmanaged Exports):

 [DllExport("Test", CallingConvention = CallingConvention.StdCall)] static int Test([MarshalAs(UnmanagedType.BStr)] out string strout) { strout = "teststr"; return 0; // indicates success } 

E sul lato Inno Setup con l’uso di WideString per questo:

 [Code] function Test(out strout: WideString): Integer; external '[email protected]:testdll.dll stdcall'; procedure CallTest; var retval: Integer; str: WideString; begin retval := Test(str); { test retval for success } Log(str); end;