Native C++ DLL mit C++/CLI



  • Hallo,

    ich habe eine DLL in C++ mit .lib und den Headern erzeugt, was auch gut funktioniert hat. In nativen Projekten linke ich gegen die .lib, inkludiere die Header Dateien und fertig. Alles klappt wunderbar.

    Nun wollte ich ein GUI bauen, welches eine grafische Schnittstelle für die DLL Funktionen bereitstellt. Da ich nur die MSVC++ Express Edition besitze, habe ich natürlich keinen Zugriff auf die MFC.

    Da mir die anderen Toolkits immer aufgrund von kleinen Details nicht zusagen, wollte ich das GUI in .NET zusammen klatschen, vor allem, weil die Designer von VS so verdammt komfortabel sind. Also wollte ich - da meine DLL ja nativ ist - das GUI mit C++/CLI machen.

    Allerdings musste ich feststellen, dass das ganze doch nicht so einfach ist, wie ich mir das vorgestellt hatte.

    Eigentlich wollte ich wie üblich gegen die .lib linken, Header inkludieren und dann direkt meine Klassen aus der DLL benutzen. Der Compiler warnt mich allerdings, dass __declspec(import) wohl nicht ganz so gern gesehen ist (warning C4272: "MyClass::MyClass": Ist als __declspec(dllimport) markiert. Beim Importieren einer Funktion muss eine systemeigene Aufrufkonvention angegeben werden.)

    Ebenfalls bekomme ich Fehler aus Dateien, mit denen ich direkt nichts zu tun habe (C:\Programme\Microsoft SDKs\Windows\v6.0A\include\objidl.h(5934) : error C2872: 'IDataObject': Mehrdeutiges Symbol), was das zu bedeuten hat, weiß ich aber nicht.

    Nun wollte ich mich erkundigen, ob es überhaupt möglich ist, eine native C++ DLL "problemlos" in C++/CLI zu verwenden oder benötige ich da erst Wrapper und ggf. sogar Änderungen an den Header Dateien?

    Vielleicht hat ja auch wer einen Link bzgl. der Thematik.

    Für eine Antwort (egal welche) wäre ich dankbar :).



  • Tipp 1: Installiere eine englische Version von VS, dann kannst Du mit den Fehlermeldungen auch was anfangen 😉

    Tipp 2:
    Du kannst in einer Managed-Klasse (ref) nur *Zeiger* auf unmanaged Klassen aufnehmen. Also anstelle:

    ref class Form1 : Form
    {
      CMyUnmanagedClass mClass;
    };
    

    schreibe

    ref class Form1 : Form
    {
      CMyUnmanagedClass *pmClass;
      Form1()
      {
        pmClass = new CMyUnmanagedClass();
      }
    };
    

    Tipp 3: Includiere die "windows.h" *nur* in Deiner cpp-Datei und nicht im Header, dann geht auch der IDataObject-Fehler weg...

    Und "JA", es ist natürlich möglich native Klassen/DLLs zu verwenden; das ist IMHO der einzige Grund warum es C++/CLI gibt 😉



  • Nunja, ich bin nun schon etwas weiter. Das Programm lässt sich kompilieren, linken und sogar ausführen!

    Allerdings wird eine AccessViolationException geworfen:

    public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    
    			arch = new File::DOArchive; // Hier fliegt die Exception
    		}
    // ...
    	private: File::DOArchive* arch;
    	};
    

    Der Anfang von DOArchive sieht so aus:

    namespace File {
    	class API_EXPORT_IMPORT DOArchive {
    	public:
    
    		explicit DOArchive(std::wstring filename = L"");
    // ...
    

    Im Konstruktor selbst (der in der nativen DLL steckt) werden Variablen Werte zugewiesen, zu Speicherverletzungen kann es da nicht kommen (in einem nativen Projekt funktioniert auch alles einwandfrei).

    Nun liegt die Vermutung nahe, dass es sich um ein Problem in Zusammenhang mit C++/CLI handelt. Irgendwelche Ideen? Ich habe das Projekt von /clr:pure auf /clr umgestellt.



  • Leg doch mal die .pdb-Datei der nativen (Debug-)DLL in das Verzeichnis der ausführbaren Datei, und gib den Pfad zu den Quellen der nativen DLL bei "Quelldateien debuggen" im Dialog Eigenschaften der Projektmappe (im Projektmappenexplorer rechte Maustaste auf die Projektmappe) an. Dann müsste der Debugger in der Lage sein noch genauer die Stelle des Absturzes zu benennen.



  • Debugge es doch einfach... dazu musst Du vermutlich noch in den Projekteinstellungen unter "Debug" "Mixed-Mode" aktvieren... (damit Du auch native Code debuggen kannst).



  • Danke für die Antworten.

    Ich habe die ganze Zeit mit der Release Version meiner DLL gearbeitet, weil die Debug-Version dank eines Kollegen unglaublich langsam in der Ausführung ist (liegt angeblich an den Secure-Iterators).

    Jetzt habe ich dann doch mal Debug-Version benutzt und - es geht.

    Vielleicht war meine DLL auch einfach nur defekt, war zuletzt ein wenig chaotisch hier.

    Danke für die Hilfe und die Tips.


Anmelden zum Antworten