Ich möchte aus C# einen String an eine C/C++ Dll übergeben, dort etwas Magie mit dem String betreiben und ihn dann im 2. Parameter an meine C#App zurückliefern. Bis auf das zurückliefern funktioniert alles reibungslos ...
// C-Code
boolean DLL_EXPORT ExterneMethodeInC(const LPCSTR input, LPCSTR pOutput)
{
char output[] = { "FEDCBA987654321\0" };
MessageBoxA(0, input, "DLL Message", MB_OK | MB_ICONINFORMATION);
MessageBoxA(0, output, "DLL Message", MB_OK | MB_ICONINFORMATION);
pOutput = output;
return TRUE;
}
[DllImport(@"E:\Users\Public\CODE\AES\AES.dll", EntryPoint = "ExterneMethodeInC")]
static extern bool ExterneMethodeInC(char[] input, [MarshalAs(UnmanagedType.LPArray)] ref char[] output);
static void Main() {
char[] a = "0123456789ABCDEF".ToCharArray();
char[] b = "0000000000000000".ToCharArray();
if (ExterneMethodeInC(a, ref b))
Console.WriteLine(b);
...
b hat nach dem Aufruf nurnoch eine Länge von 1 und es steht nur die eine '0' aus der Initialisierung drin'.
Bin dankbar für alle sachdienlichen Hinweise.
Ist es nicht so ganz. Meine dll funktioniert. Die beiden MessageBoxen die testweise aufpoppen sollen enthalten die korrekten Daten. Nur bekomme ich den string nicht aus c zurück nach c#. 😦
Das tut mir leid, ich hab nur die Frage:
eingefügt, bringt aber nichts. Bei der Dll kommt immer nur der ERSTE BUCHSTABE des übergebenen Strings an!!!!?!?!
Wieso das? Was kann ich tun bzw. was mache ich falsch?
in dem oben stehenden Link gesehen und dachte daher es könnte helfen.
lpcstr ist ein nullterminiertes ansi char array -> byte[]
char[] in c# ist ein unicode array -> ushort[]
in c ist ein char 1 byte. in c# ist ein char 2 bytes. wenn man c# zeichen an c übergibt, wird ein char als 2 chars interpretiert. die lateinischen buchstaben haben aber alle noch die alten nidrigen werde. deshalb enthält das zweite char in c dann den wert 0, also '\0', was in c da<s Ende des strings markiert -> alles wird nach 1 zeichen abgeschnitten!Du
übergibst du faktisch "0\01\02\03\04\0....
[DllImport(@"E:\Users\Public\CODE\AES\AES.dll", EntryPoint = "ExterneMethodeInC")]
static extern [MarshalAs(UnmanagedTypoe.Bool)] bool ExterneMethodeInC([MarshalAs(LPStr),In]string input, [MarshalAs(UnmanagedType.LPStr),In,Out] StringBuilder output);
StringBuilder b = new StringBuilder(512/*max. länge*/);
b.Append("0000000000000000");
if (ExterneMethodeInC("0123456789ABCDEF", b))
Console.WriteLine(b.ToString());
Vielen Dank, sieht schonmal besser aus ... aber meine Ausgabe auf der Console ist jetzt ... die Nullen die Du in den StringBuilder reingestopft hast ... liegt der Fehler vlt eher auf der c/c++ Dll-Seite?
liegt der Fehler vlt eher auf der c/c++ Dll-Seite?
pOutput=output ist komplett wirkungslos!
Möglichkeit a. (standard))
du ersetzt die zuweisung durch strcopy(output,pOutput) (parameter vllt vertauschen)
nachteil: du hast eine maximale stringlänge
Möglichkeit b.)
Parameter bekommt ein sternchen: LPCSTR* pOutput
...
*pOutput=output;
nachteil:
1.) deine c- dll muss eine freestring-funktion exportieren, sodass du den string wieder loswirst und diesye funktion musst du selber aufrufen.
2.) du musst dich in c# selbst mit pointern rumschlagen und hast kein automatisches übersetzen nach stringbuilder oder array oder so
Möglichkeit 3:
boolean DLL_EXPORT ExterneMethodeInC(const LPCSTR input, LPCSTR pOutput, DWORD pOutputLen);
Verwendung:
Stringbuilder buffer = new StringBuilder(1024);
if (ExterneMethodeInC(input, buffer, buffer.Capacity - 1)) //-1: nullterminierung
Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...