Laden...

String von unmanaged zu managed und zurück C dll

Erstellt von ExceptionMagnet vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.684 Views
E
ExceptionMagnet Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren
String von unmanaged zu managed und zurück C dll

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.

E
92 Beiträge seit 2008
vor 13 Jahren

Hey!
Ich weiß nicht mehr genau ob es letzendlich das gleiche Problem war, aber zumindest sehr ähnlich, vielleicht hilft es:

Hier

Am Anfang gehts da noch um etwas anderes, ließ weiter, dann gehts um Strings 😉

E
ExceptionMagnet Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren

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#. 😦

E
92 Beiträge seit 2008
vor 13 Jahren

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.

1.130 Beiträge seit 2007
vor 13 Jahren

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());

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

E
ExceptionMagnet Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren

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?

1.130 Beiträge seit 2007
vor 13 Jahren

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

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

E
ExceptionMagnet Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren

A!!! und wir sind glücklich 😉
Vielen Dank für Eure Hilfe.

3.971 Beiträge seit 2006
vor 13 Jahren

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...

1.130 Beiträge seit 2007
vor 13 Jahren

Möglichkeit 3

maximale Länge wird so ebenfalls VOR dem aufruf festgelegt.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!