Autor Beitrag
DerDieter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: So 19.11.17 19:11 
Hallo,

ich habe ein kleines Problem und zwar möchte ich einen ulong array in C# zu einer Delphi DLL übergeben, diese dort mit Werten füllen und wieder zurück zum C# Hauptprogramm geben.
Das ganze funktioniert problemlos für nicht-arrays, hier ein Beispiel was funktioniert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure Test(out i: ptruint;) stdcall;
begin
 out := InternalTest(); // InternalTest() gibt einen ptrUint wert zurück.
end;


und in C#:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
 [DllImport("test.dll")]
 public static extern void Test(ref ulong i);

//....
ulong i = 0;
Test(i);
MessageBox.Show(i.ToString());


Das funktioniert einwandfrei.
Aber wenn ich das ganze mit einem Array probiere bekomme ich eine externe Exception:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure Test(out i: array of ptrUint;) stdcall;
begin
 out[0] := InternalTest();  // InternalTest() gibt einen ptrUint wert zurück.
end;


und in C#:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
 [DllImport("test.dll")]
 public static extern void Test(ref ulong[] i);

//....
ulong[] i = new ulong[3];
Test(i);
MessageBox.Show(i[0].ToString());


Ich habe folgende Varianten auch schon ausprobiert aber das klappt einfach nicht:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
 [DllImport("test.dll")]
 public static extern void Test(ref [MarshalAs(UnmanagedType.LPArray] [In, Out]ulong[] i);

[DllImport("test.dll")]
 public static extern void Test(ref [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2] [In, Out] ulong[] i);


Bitte helft mir :(
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: So 19.11.17 20:10 
Hallo und :welcome:

ein Array ist schon ein Referenztyp, daher laß mal ref weg:
ausblenden C#-Quelltext
1:
2:
[DllImport("test.dll")]
public static extern void Test(ulong[] array);

Außerdem noch die Frage: Ist bei dir in Delphi int 64bit groß (denn ein ulong in C# ist es)? Ansonsten auch in C# uint verwenden.
DerDieter Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: So 19.11.17 21:36 
Hallo Th69 und vielen Dank für die Antwort, das klappt super! Und ja ist 64bit groß.

Jetzt habe ich aber das Problem, dass er bei Strings den Dienst verweigert, das Programm stürzt immer ab wenn ich die Dll Funktion aufrufe.
Hier mein Code:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure Test(out s: array of stringstdcall;
begin
 out[0] := InternalTestStr();  // InternalTestStr() gibt einen string wert zurück.
end;


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
string[] s = new string[] { """""""""" };
Test(s);
MessageBox.Show(s[0]); 

[DllImport("test.dll")]
 public static extern void Test(string[] s);


Ich habe gelesen das man bei Strings [MarshalAs(UnmanagedType.BStr)] benutzen soll. Aber da meckert der Kompiler und verlangt ByValArray bzw. LpArray (beides hat aber auch nicht funktioniert).
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: Mo 20.11.17 11:19 
Hallo,

von welchem genauen Delphi-String sprichst du? Ein shortstring (in Delphi) ist ein spezieller Datentyp, welcher gesondert behandelt werden muß: How can I marshal a Delphi short string using p/invoke?
Das ".NET P/Invoke String Marshalling" basiert ja standardmäßig auf nullterminierten Strings (wie in "C").