Autor Beitrag
Tastaro
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 414
Erhaltene Danke: 23



BeitragVerfasst: Di 12.09.17 11:34 
Hallo,

ich habe in eine Delphi-DLL eine Funktion die so aussieht:

ausblenden Delphi-Quelltext
1:
function foo(pcResultBuffer: pchar; iResultBufferSize: integer): integer; stdcall;					

In pcResultBuffer wird ein String zurückgegeben. iResultBufferSize teilt die Größe des Buffers mit, auf den pcResultBuffer zeigt.

Diese möchte ich unter C# verwenden.
Ich importiere die DLL dynamisch. Also lege ich einen Typ an (Ist das so richtig?):

ausblenden C#-Quelltext
1:
2:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate int FooCallbackType([MarshalAs(UnmanagedType.LPStr)] string resultBuffer, int resultBufferSize);


... der dann verwendet wird

ausblenden C#-Quelltext
1:
private FooCallbackType fooCallback = null;					


Das Auslesen der Funktionszeiger:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private void GetProcAddresses()
{
    IntPtr funcAddr = IntPtr.Zero;
    
    funcAddr = GetProcAddress(dllHandle, "foo");
    if (funcAddr != IntPtr.Zero)
        fooCallback = (FooCallbackType)Marshal.GetDelegateForFunctionPointer(
            funcAddr, typeof(FooCallbackType));
}


Jetzt fehlt noch der Aufruf der Funktion. Wie mache ich das? Genauer: Wie initialisiere ich den Buffer auf eine bestimmte Länge, damit die Delphi-Funktion was hineinschreiben kann?

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
string resultBuffer;
int bufferSize;
int charsInBuffed;

//hier Buffer-Initialiserierung ????

charsInBuffed = foo(resultBuffer, bufferSize);


Oder muss man das ganz anders machen?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 12.09.17 12:04 
Lies dir mal Using the StringBuilder in Unmanaged API Calls durch (Lösung bei dir also entsprechend "2.4 Using StringBuilder").

Für diesen Beitrag haben gedankt: Tastaro
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 12.09.17 12:14 
- Nachträglich durch die Entwickler-Ecke gelöscht -

Für diesen Beitrag haben gedankt: Tastaro
Tastaro Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 414
Erhaltene Danke: 23



BeitragVerfasst: Di 12.09.17 12:41 
@Frühlingsrolle: GetProcAddress ist schon klar. Das dynamische Einbinden klappt wunderbar.
Ich binde DLLs lieber dynamisch als statisch ein, dann habe ich eine bessere Kontrolle über das Verhalten meines Programms, wenn die DLL nicht vorhanden ist. In manchen Fällen wird sie auch gar nicht benötigt.

Mir ging es hauptsächlich um die Rückgabe eines Strings in einem Buffer.

@Th69: Danke für den Link. Das werde ich mal probieren.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 12.09.17 14:53 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Tastaro Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 414
Erhaltene Danke: 23



BeitragVerfasst: Mi 13.09.17 12:04 
@Frühlingsrolle: Die Delphi-Funktion erwartet, dass der Speicher des Buffers schon reserviert ist. Mit der Variante gäbe es eine Zugriffstverletzung.

@Th69: Mit dem StringBuilder klappt es super. Danke!