.Net-DLL in Ansi C Projekt nutzen



  • Hallo zusammen,

    ich habe gerade folgendes Problem und hoffe, ihr könnte mir da weiter helfen, da ich keinen Ansatz finde.

    Ich habe ein Projekt, geschrieben in ANSI C. Nun soll ich einen Teil des Projektes auslagern und neu implementieren. Dazu soll ich Visual Studio 2010 C++ nutzen. Ich habe also ein Projekt gestartet (Win32-Projekt) und habe eine DLL (+.lib Datei) erstellt. Diese konnte ich dann in dem ANSI-C Projekt wiederum nutzen. Das hatte funktioniert.

    Mir ist dann aber schnell aufgefallen, dass ich auf die .Net-Klassen nicht zugreifen konnte. Daher habe ich ein neues Projekt (Klassenbibliothek) gestartet. Hier scheint es so, als könne ich die .Net Bibliotheken nutzen. Nun habe ich aber das generelle Verständnisproblem, wie ich weiter vorgehen muss. Es wird eine DLL erstellt (ohne LIB!!!) die ich ja jetzt nicht ohne weiteres im ANSI-C Projekt nutzen kann, oder? Was muss ich tun, damit ich eine DLL+lib erstellt bekomm, die ich wieder im alten Projekt nutzen kann?

    Ich weiß leider nicht, nach was ich suchen soll zu diesem Thema!!
    Vielen Dank für eure Hilfe!

    Gruß



  • Wenn du die DLL in deinem ANSI-C-Projekt nutzen willst, muss die Schnittstelle der DLL natürlich eine reine C-Schnittstelle sein. Wenn du VC++ nimmst, kannst du bei einem DLL-Projekt auch die CLI-Unterstützung aktivieren.

    Das VS haut für DLL-Projekte eigentlich automatisch eine Lib mit raus, außer es wird nichts exportiert! Hast du mit __declspec(dllexport) die Funktionen markiert, welche die DLL exportieren soll? Oder hast du eine DEF-Datei verwendet?
    Außerdem würde ich alle zu exportierenden Funktionen mit extern "C" umschließen, um das name mangline zu unterbinden.

    MfG Pellaeon



  • Hallo Pellaeon,

    ich danke dir für die schnelle Antwort. habe es jetzt so gemacht, wie du es gesagt hast und bis jetzt scheint mal alles zu funktionieren.

    Ich habe nun folgendes gerüst gewählt:

    Header-Datei:

    #ifdef PROJECT_EXPORTS
    #define DLLINTERFACE __declspec(dllexport)
    #else
    #define DLLINTERFACE __declspec(dllimport)
    #endif
    
    #ifdef __cplusplus
        extern "C" {
    #endif
    
    	DLLINTERFACE int Init(void); //extern sichtbare C-Funktion
    
    #ifdef __cplusplus
        }
    #endif
    
    #pragma once
    
    using namespace System;
    using namespace System::IO;
    
    namespace test1 {
    
    	public ref class Class1
    	{
    		// TODO: Die Methoden für diese Klasse hier hinzufügen.
    	public: 
    		void testMethode(void);
    	};
    }
    
    #endif
    

    CPP-Datei:

    #include "stdafx.h"
    
    #include "test1.h"
    
    using namespace test1;
    
    DLLINTERFACE int Init(void)
    {
      return 0;
    }
    
    void Class1::testMethode(void)
    {	
    
    }
    

    Jetzt habe ich noch eine Frage. Wenn ich diese DLL nicht mehr in einem reinen C-Projekt nutzen möchte, sondern z.B. in einem C#.Net Projekt, wie kann ich dann die Klasse nach außen sichtbar machen. Ich habe z.B. versucht, die Klasse an sich und auch die Methoden mit dem define "DLLINTERFACE" zu versehen. Leider kommt dann foglende Meldung:

    public ref class Class1
    {
    // TODO: Die Methoden für diese Klasse hier hinzufügen.
    public: 
    	void DLLINTERFACE testMethode(void);
    };
    

    error C3387: 'testMethode': __declspec(dllexport)/__declspec(dllimport) kann nicht auf ein Member eines verwalteten Typs angewendet werden

    Dazu vielleicht auch noch eine Idee??
    Danke!



  • Also wie man direkt die C#-Klasse jetzt exportiert aus deinem C++-Dll-Projekt kA. Ich würde mir wahrscheinlich einfach ein neues C#-Projekt im selben Ordner anlegen, was auf die selben Quellcode-Dateien zugreift.
    Aber evtl. kann da jemand anders noch was zu sagen.



  • skluge schrieb:

    Ich habe ein Projekt, geschrieben in ANSI C. Nun soll ich einen Teil des Projektes auslagern und neu implementieren. Dazu soll ich Visual Studio 2010 C++ nutzen...

    Und mit was für einer Sprache? C++ oder C++/CLI?

    skluge schrieb:

    Mir ist dann aber schnell aufgefallen, dass ich auf die .Net-Klassen nicht zugreifen konnte.

    Ein Win32-Projekt unterstützt auch kein .Net, da es für "native" Programmierung ausgelegt ist, und .Net ist nun einmal nicht für native Programmierung ausgelegt. Es gibt eine .Net Sprache, die C++ ähnelt (C++/CLI) die man als Bindeglied zwischen .Net und nativen Code ansehen kann (Aber C++/CLI ist dennoch KEIN C++, gewisse Unterschiede gibt es nun einmal).

    Um eine .Net dll zu verwenden gibt es nun mindestens 2 Wege:

    1. Du schreibst mittels C++/CLI eine DLL als Wrapper (wenn die DLL selbst nicht schon C++/CLI ist), und verpasst ihr eine C-Kompatible Schnittstelle. Und nein, eine C-Schnittstelle akzeptiert logischerweise keine Klassenübergaben (zumal managed-Klassen nicht über Zeiger verwaltet werden, und auch nicht binärkompatibel zur nativen Welt sind).

    2. Du verpasst der .Net dll eine COM-Schnittstelle (soviel ich weiß, ist das nur eine Einstellung im Projekt - musst aber selbst nachschauen), und verwendet zur Interaktion COM.



  • skluge schrieb:

    Ich habe nun folgendes gerüst gewählt:

    Was du auch gleich wieder wegwerfen kannst. Die .Net Welt und die native Welt sind miteinander inkompatibel (Sprich: Es gibt keine direkte Möglichkeit eine .Net Schnittstelle in die native Welt zu exportieren, ohne ihr einen komplett nativen Wrapper zu verpassen, oder über COM zu gehen).

    skluge schrieb:

    Jetzt habe ich noch eine Frage. Wenn ich diese DLL nicht mehr in einem reinen C-Projekt nutzen möchte, sondern z.B. in einem C#.Net Projekt, wie kann ich dann die Klasse nach außen sichtbar machen.

    Das wiederum ist einfach: Lasse dein DLLINTERFACE weg. .Net erfordert keinen solchen Aufwand für den Export.

    Ich bin zwar nicht mit C++/CLI sonderlich firm, aber für das Verwenden in einem anderen .Net Programm sollte folgendes ausreichen:

    public ref class Class1
    {
      public: 
        void testMethode();
    };
    

    Und schließlich diese dll als Referenz in z.B. deinem C# Programm einfügen. Das "public" bei einer .Net Klasse sagt bereits aus, das sie von außerhalb der DLL sichtbar (und verwendbar) ist.

    Nachtrag: Genau dieses "leichte" miteinander von verschiedenen DLLs finde ich einen der wesentlichen Vorteile in einer reinen .Net Umgebung.

    2. Nachtrag: Könnte ein Moderator bitte diesen Thread in das C++/CLI-Unterforum verschieben, das sollte dort deutlich besser hinein passen.



  • asc schrieb:

    Ein Win32-Projekt unterstützt auch kein .Net, da es für "native" Programmierung ausgelegt ist

    Eigenschaften -> Allgemein->Common Language Runtime-Unterstützung

    Natürlich kannst du in einem Win32-Projekt .NET benutzen. Das ist dann nicht mehr nativ, weil man das .NET-Framework in der DLL benötigt, aber nach außen hin ist es eine einfache C-DLL. In diesem Projekt kann man dann normal C++ programmieren und das .NET dann zB in C++/CLI.

    Wieviel Sinn das ganze macht, den Aufwand zu betreiben, das muss der Threadersteller wissen. Ich hatte auch schon eine Situation, wo ich ein Grafiksystem mit .NET-Schnittstelle an mein MFC-Programm anbinden musste. Hab ich dann ebefalls über eine DLL gemacht.



  • Hallo asc:

    asc schrieb:

    1. Du schreibst mittels C++/CLI eine DLL als Wrapper (wenn die DLL selbst nicht schon C++/CLI ist), und verpasst ihr eine C-Kompatible Schnittstelle. Und nein, eine C-Schnittstelle akzeptiert logischerweise keine Klassenübergaben (zumal managed-Klassen nicht über Zeiger verwaltet werden, und auch nicht binärkompatibel zur nativen Welt sind).

    Leider ist diese Welt für mich neu, also verzeih mir, wenn ich jetzt ein paar doofe fragen stell.

    1. Wenn ich ein Klassenbibliotheks-Projekt erzeuge (keine Einstellungen geändert) und das von mir oben aufgeführte Gerüst nutze, beschreibt das nicht genau deinen Punkt Nr.1?

    2. Bedeutet das im Endeffekt, dass ich zwei Projekte aufmachen muss? Zum einen das Klassenbibliotheks-Projekt (.Net) das eine DLL erzeugt, die ich aber nicht in LabWindows (IDE für das ANSI_C Projekt) nutzen kann. Zum anderen ein C++ Wrapper Projekt, dass mir Schnittstellen bereitstellt, die ich dann in LabWindows nutzen kann??

    3. Kann ich auch was mit dem Stichwort "P/Invoke" erreichen?

    Danke



  • Pellaeon schrieb:

    Das ist dann nicht mehr nativ, weil man das .NET-Framework in der DLL benötigt, aber nach außen hin ist es eine einfache C-DLL.

    In seinen Fall ist es aber keine "einfache" C-DLL, da er versucht eine .Net Klasse zu exportieren. Eine C-Schnittstelle muss nun einmal ausschließlich mit Funktionen und Datentypen die C kennt aufgebaut sein (und man kann auch nicht einfach mal über void-Zeiger auf Objekte verweisen, da managed Objekte nunmal im Speicher verschoben werden können (Was die .Net Referenzen berücksichtigen).

    skluge schrieb:

    3. Kann ich auch was mit dem Stichwort "P/Invoke" erreichen?

    Nein, das wäre der umgekehrte Fall (C-Bibliothek in .Net verwenden). Du brauchst eine C-Schnittstelle (ob nun aus einem Projekt was C++/CLI verwendet, oder in dem du COM verwendest).



  • asc schrieb:

    Nein, das wäre der umgekehrte Fall (C-Bibliothek in .Net verwenden). Du brauchst eine C-Schnittstelle (ob nun aus einem Projekt was C++/CLI verwendet, oder in dem du COM verwendest).

    OK... wenn du von C-Schnittstelle redest, dann verstehe ich folgendes Konstrukt:

    #ifdef __cplusplus
        extern "C" {
    #endif
    
        DLLINTERFACE int Init(void); //extern sichtbare C-Funktion
    
    #ifdef __cplusplus
        }
    #endif
    

    in diesem Block kann ich dann die C-Funktionen definieren, die nach außen hin sichtbar sind. Diese wiederum verweisen einfach auf meine member-methoden der Klasse, oder? Ich hoffe, dass ich da nix verwechsle.

    Hättest du für meinen Fall.. also .Net-DLL für unmanaged Code vorbereiten vielleicht ein Tutorial, das mir dabei hilft? Das wäre super. Toll wäre es, wenn das Tutorial auch genau diesen Aspekt, C-Schnittstelle und .Net Implementierung abdeckt. Hinzu kommt ja noch, dass ich in meiner .Net-DLL auch extrene win32-dll nutzen muss. Anscheinend werde ich da auch noch schwierigkeiten bekommen.



  • skluge schrieb:

    vielleicht ein Tutorial,

    Gute Onlinequellen zu diesem Thema würden mich auch mal interessieren.

    Die beste Beschreibung zu mixed DLLs habe ich bisher in diesem Buch gefunden:
    http://apress.com/book/view/9781590597569
    Interessant ist der Teil ab S. 157, dummerweise zeigt die Google Suche genau diese Seiten nicht an.

    Dort wird Schritt für Schritt beschrieben, wie man aufbauend auf einem Win32 DLL Projekt CLR-Klassen hinzufügt und wie man die Visual Studio Projekteigenschaften einstellen muss, damit man z.B. getrennte vorkompilierte Header für managed und unmanaged hat.


Log in to reply