C# auf c++ Wrapper Problem



  • Hallo,

    Folgendes Szenario:
    Ich möchte auf eine C# DLL von einer C++ Quelle zugreifen. Damit so etwas geht habe ich mir einen Managed C++ Wrapper geschrieben und die Methoden exportiert.

    Hier die Managed C++ Wrapper Klasse:

    extern "C" __declspec(dllexport) int _stdcall GetXML(char** str)
    {
    	System::String ^ xmlString = CSharpSchnittstelle::GetXML();
    	System::IntPtr ptr = System::Runtime::InteropServices::Marshal::StringToHGlobalUni(xmlString);
    	*str = static_cast<char*>(ptr.ToPointer());
    	return 0;
    }
    
    extern "C" __declspec(dllexport) int _stdcall SendXML(char* str)
    {
    	System::IntPtr *ptr = new System::IntPtr(str);
    	CSharpSchnittstelle::SendXML(*ptr);
    	return 0;
    

    Hier die C# .NET Klasse:

    public static string GetXML()
            {
                string str = "TestXMLString";
                return str;
            }
    
            public static void SendXML(IntPtr ptr)
            {
                try
                {
                    string xmlString = Marshal.PtrToStringAuto(ptr);
                    Marshal.FreeHGlobal(ptr);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.ToString());
                }
            }
    

    Hier das Testprogramm unter C++:

    char* xmlString;
    printf("Hole XML-Daten\n");
    GetXML(&xmlString);
    printf("Sende XML-Daten\n");
    SendXML(xmlString);
    printf("Sende XML-Daten 2\n");
    char* str = "Test";
    SendXML(str);
    
    printf("\nTaste druecken zum Beenden ...\n");
    getch();
    
    return 0;
    

    Nun mein Problem.
    Die Methode GetXML funktioniert perfekt, in c++ kommt mein Inhalt (gesendet von c#) korrekt an.
    Sende ich diesen auch direkt wieder kommt er auch in C# an.

    Mache ich aber nur

    char* str = "Test";
    SendXML(str);
    

    kommt in C# eine Exception, dass das Handle ungültig ist und kein Inhalt wird gesendet.

    Was ist der Unterschied, wenn ich den empfangene Inhalt direkt nochmal sende (das geht ja) gegenüber ein String char* manuell erzeuge und diesen sende?

    Wie kann man das lösen?

    Gruß
    Christof



  • Klappt es, wenn Du den Speicher auf dem Heap anlegst ?



  • Knuddlbaer schrieb:

    Klappt es, wenn Du den Speicher auf dem Heap anlegst ?

    Wie geht das?



  • char * text = new char[20];

    Ich denke das Problem hängt mit der Speicherart zusammen. Ich habe mich mit dem Marshall zeugs nicht wirklich beschäftigt, könnte mir aber vorstellen das ein hin und her wandeln des Speichers mit "Stackspeicher" kollidiert.

    Wie schaut es eigentlich mit der Speicherverwantortlichkeit aus bei der Marshal sache ?



  • Knuddlbaer schrieb:

    char * text = new char[20];

    Ich denke das Problem hängt mit der Speicherart zusammen. Ich habe mich mit dem Marshall zeugs nicht wirklich beschäftigt, könnte mir aber vorstellen das ein hin und her wandeln des Speichers mit "Stackspeicher" kollidiert.

    Das hat leider nicht funktioniert.

    Knuddlbaer schrieb:

    Wie schaut es eigentlich mit der Speicherverwantortlichkeit aus bei der Marshal sache ?

    Das ist eine gute Frage? 😕



  • Warum machst Du Deine C#-Klasse nicht "sinnvoll"? Also direkt den "string" verwenden und lass das IntPtr weg!


Anmelden zum Antworten