C# string an C++ dll übergeben



  • Hallo,

    Ich habe eine in unmanaged C++ geschriebene DLL in C# eingebunden. Nun möchte ich eine Funktion aufrufen welche zwei (C++)Strings erwartet. Das Problem hierbei ist nur dass wenn ich diese Funktion in C# aufrufe und die Strings übergebe, hängt sich das ganze Programm auf(APPCRASH), wenn dich diese strings gleich in der C++ Funktion implementiere funktioniert alles einwandfrei.
    Hier die C++ Funktion:

    __declspec(dllexport) int send(string ip_s, string ip_t)
    

    C# Einbindung:

    [DllImport("send.dll", EntryPoint = "#1", ExactSpelling = true)]
    public static extern int send(String ip_s, String ip_t);
    

    und der Aufruf in C#:

    int i = send("192.168.000.020", "192.168.000.100");
    

    Habe gehört, dass ein c# string != c++ string ist, finde jedoch nirgends eine Lösung.

    Danke im voraus!

    Verwende VS2010 Prof. mit .NET 4.0 auf W7 Prof.

    MfG, dll



  • Hallo,

    ja, ein C#-String (System.String) ist intern ganz anders aufgebaut als ein C++ String (std::string).
    Könntest du die DLL-Funktion so ändern, daß sie einen (bzw. zwei) "const char *" entgegennimmt? Außerdem dann die Funktion mittels

    extern "C"
    {
      int send(const char *ip_s, const char *ip_t);
    }
    

    exportieren, d.h. als reine C-Schnittstelle (d.h. kein Name-Mangling).
    Dann kannst du deinen C# Code so lassen und die Funktion ordnungsgemäß aufrufen (das .NET-Marshalling kann intern einen System.String als "const char *" übergeben).
    Wobei ich selber anstatt über den "EntryPoint" eher mittels des Namens die Funktion ansprechen würde, d.h.

    [DllImport("send.dll", ExactSpelling = true)]
    public static extern int send(String ip_s, String ip_t);
    


  • Hey,

    Danke jetzt funktioniert alles wunderbar!
    Das mit dem EntryPoint ist so ne Sache.. wenn ich keinen festlege, wird keiner gefunden und es funktioniert erst nicht, da die DLL sowieso nur eine Func. enthält ist es allerdings egal.

    MfG



  • Hallo Th69,

    ich weiß, das Thema ist schon 1 Jahr alt. Es hat mir gerade geholfen. Könnte mir trotzdem jemand mal kurz den Zusammenhang erklären? Mit Zeigern und Referenzen habe ich in C++ noch so meine Schwierigkeiten.

    Verstanden habe ich, dass in C# Strings wohl einen anderen Aufbau haben als c++ Strings. Wenn ich das jetzt so schreibe, wird es mir zumindest teilweise klar: strings sind keine Grundtypen sondern Objekte einer Klasse, die wohl in C++ un C# unterschiedlich aufgebaut sind.

    Jetzt habe ich also einen C#-String an eine extern "C" Funktion übergeben. Die Funktion nimmt ihn als const char *name entgegen. Was mache ich jetzt damit?

    Danke Jens



  • Hallo xenayoo,

    was willst du denn mit dem String intern machen? Im einfachsten Fall kannst du einfach in deinem C++ Code den std::string Datentyp benutzen und damit weiterarbeiten:

    void my_string_function(const char *str)
    {
      std::string my_string(str);
    
      // und hier jetzt mit my_string weiterarbeiten
    }
    


  • Hallo TH69,

    danke, das hilft mir bereits weiter. Nur für's Verständnis:
    in C# wird beim Funktionsaufruf ein String übergeben.
    in C++ wird dieser string als const char * strname entgegen genommen. D.h. als Zeiger auf ein Datenbereich vom Typ char - der darüber hinaus noch const ist - also nicht verändert werden kann.

    Frage: Liegt die Zeichenkette im Speicher der Dot-Net-Runtime-Umgebung und der char-Zeiger zeigt auf diesen Speicherbereich oder liegt die Zeichenkette nach Übergabe durch den Funktionsaufruf irgendwo im Speicher und ist nur durch diesen Zeiger erreichbar. Damit dieser Zusammenhang nicht verloren geht, ist der Zeiger durch const unveränderbar.

    ich verstehe halt gerne, was ich mache.... 🙂

    Danke,

    Jens


Anmelden zum Antworten