Globales Objekt gebraucht?!?



  • Hallo zusammen,

    ich beschäftige mich gerade neu mit der Thematik C++/CLI und habe ein paar generelle Verständnisfragen, aber auch konkrete Probleme.

    Ich habe die Aufgabe, einen kleinen Teil eines bestehendes Projekts (ANSI-C; IDE: LabWindows) in .Net C++ zu portieren. Dabei soll dieser Teil später wieder als (.Net)DLL dem ANSI-C Projekt bereitstehen und genutzt werden können. das alte Projekt besteht aus einem Hauptprogramm, dass sich seine Funktionalität aus mehreren (selbstgebauten)C-DLLs besorgt.

    Dabei sollen, so weit es geht, die bestehenden Funktionen des kleinen Teils mit .Net Funktionen ersetzt werden. Jedoch müssen manche Funktionen aus den C-DLLs genommen werden, da Sie von .Net nicht ohne weiteres unterstützt werden.

    Ich habe in VS2010 nun eine Klassenbibliotheks-Projektvorlage gestartet und versucht, ein Codegerüst für die DLL zu erstellen. Dieses Gerüst sieht wie folgt aus:

    HEADER-Datei:

    #ifdef PROJECT_EXPORTS
    #define DLLINTERFACE __declspec(dllexport)
    #else
    #define DLLINTERFACE __declspec(dllimport)
    #endif
    
    #ifdef __cplusplus
        extern "C" {
    #endif
       //Hier sollen alle externen Funkntionen definiert werden, die ich dann
       //im alten ANSI-C Projekt nutzen kann
       DLLINTERFACE int Beispielfunktion(int);
    #ifdef __cplusplus
        }
    #endif
    
    #ifdef __cplusplus
    
    #pragma once
    
    using namespace System;
    using namespace System::IO;
    
    namespace TestProjekt {
    
    	public ref class cTestClass
    	{
    
    	public:
             //Hier sollen die Klassen-Eigenschaften etc. definiert werden
             int managedBeispielfunktion(int);
    
            };
    }
    
    #endif
    

    CPP-Datei:

    // Dies ist die Haupt-DLL.
    
    #include "stdafx.h"
    using namespace TestProjekt;
    
    //Hier kann man kein globales Objekt der managed-typ Klasse anlegen...
    Class1 ^objClass1 = gcnew Class1;
    
    DLLINTERFACE int Beispielfunktion(int iWert)
    {
       return Class1->managedBeispielfunktion(iWert);    
    }
    
    int Class1::managedBeispielfunktion(int iManagedWert)
    {
       //z.B.:
       return iManagedWert+1;
    }
    

    Ich denke mir ja, dass mein Gerüst einen völlig falschen Ansatz hat. Oder?!?!
    Wie kann ich denn meine Idee umsetzen, wenn ich kein Globales Objekt einer managed Klasse anlegen kann?? Wieso geht das eigentlich nicht?

    Ich muss dafür sorgen, dass ich die erstellten .Net-Dll auch wieder in dem ANSI-C Projekt nutzen kann. Daher wollte ich mit den DLLINTERFACE-Funktionen eine Art Schnittstelle zwischen diesen beiden Bereichen umsetzen. Aus dem ANSI_C Projekt wird sozusagen die Schnittstellenfunktion "Beispielfunktion" aufgerufen, die in dem .Net Bereich die Funktion "managedBeispielfunktion" aufruft. Wie kann ich es anders lösen, wenn diese Lösung nicht so toll ist?

    Des Weiteren frage ich mich, wie ich generell damit umgehen soll, dass ich kein globales Objekt anlegen kann?! Ich hatte überlegt, eine unmanaged Klasse zu erstellen, die wiederum eine Instanz der managed Klasse besitzt... aber leider erlaubt das der Compiler auch nicht.

    Ich hoffe wirklich, dass ihr mir hier weiterhelfen könnt. Vielleicht mit neuen Denkanstößen oder auch Beispiele aus dem Netz!!! Danke schon mal für eure Antworten.

    Gruß



  • Wenn Du eine DLL in C verwenden willst, darfst Du keine Klassen verwenden ("cTestClass"), sondern nur einfache Funktionen (also wie "Beispielfunktion").

    Auch verstehe ich nicht ganz warum Du .NET in deinem C programm verwenden willst. Dir muss bewusst sein, dass ein Dein alten C Programme die komplette .NET Umgebund reingeladen wird... auch wenn Du dies in einer DLL Kapselst.



  • Jochen Kalmbach schrieb:

    Auch verstehe ich nicht ganz warum Du .NET in deinem C programm verwenden willst. Dir muss bewusst sein, dass ein Dein alten C Programme die komplette .NET Umgebund reingeladen wird... auch wenn Du dies in einer DLL Kapselst.

    Hallo Jochen...

    ich selbst habe die Entscheidung, .Net zu nutzen nicht getroffen. Es handelt sich um ein historisch gewachsenes Programm, dass auf C basiert. Aus mehreren Gründen ist es natürlich sinnvoll, auf das .Net-Framework zu wechseln. Leider kann man das Projekt (auch aus Kostengründen) nicht ohne weiteres komplett auf .Net portieren. Daher soll nach und nach einzelne Module in .Net portiert werden.

    Jochen Kalmbach schrieb:

    Wenn Du eine DLL in C verwenden willst, darfst Du keine Klassen verwenden ("cTestClass"), sondern nur einfache Funktionen (also wie "Beispielfunktion").

    Daher habe ich ja auch in dem Block

    #ifdef __cplusplus
        extern "C" {
    #endif
    

    die Möglichkeit, globale (externe) Funktionen zu definieren, die ich unter C nutzen kann. Ich hoffe halt, dass mein Codegerüst so OK ist.



  • skluge schrieb:

    Ich denke mir ja, dass mein Gerüst einen völlig falschen Ansatz hat.

    Ja, sinnvoller wäre es mit einer unmanaged DLL zu beginnen und in managed Code geschriebene Teile hinzuzufügen.

    Hab ich da auch schon geschrieben ...
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-269243-and-start-is-10.html
    Du hast nicht einmal geantwortet, sondern stellst die selbe Frage nochmal im anderen Unterforum. Deswegen ist das hier auch meine letzte Anwort, die du wahrscheinlich eh ignorieren wirst, aber andere interessiert es ja vielleicht.

    Die Implementierung von deinem DLLINTERFACE ist auch Murks und geht nur mit C++ und nicht mit C.

    #ifdef __cplusplus
    	#define EXTERN	extern "C"
    #else
    	#define EXTERN	extern
    #endif
    
    #ifdef PROJECT_EXPORTS
      #define DLLINTERFACE __declspec(dllexport) __stdcall
    #else
      #define DLLINTERFACE __declspec(dllimport) __stdcall
    #endif
    
    /...
    
    EXTERN int DLLINTERFACE EineExportierteFunktion();
    

    Und lass diesen anderen #ifdef __cplusplus Quatsch weg, benutze eine Headerdatei für die C++/CLI Sachen und eine für den unmanaged Teil, dein C-Client kann mit dem C++/CLI Zeug eh nichts anfangen.

    skluge schrieb:

    Wie kann ich denn meine Idee umsetzen, wenn ich kein Globales Objekt einer managed Klasse anlegen kann??

    Das Designpattern "Singleton" ist dir kein Begriff ?

    skluge schrieb:

    Wieso geht das eigentlich nicht?

    Weil es in .net keine globalen Objekte gibt, so einfach ist das.



  • nn schrieb:

    Du hast nicht einmal geantwortet, sondern stellst die selbe Frage nochmal im anderen Unterforum. Deswegen ist das hier auch meine letzte Anwort, die du wahrscheinlich eh ignorieren wirst, aber andere interessiert es ja vielleicht.

    Tut mir leid, dass ich dich verärgert habe!! Dein Tipp in dem anderen Thread ist bestimmt hilfreich... Leider habe ich das passende Buch, welches du empfohlen hast, nicht zur Verfügung. Und da du ja schon selbst angemerkt hast, dass man über die googlePreview nicht den Teil einsehen kann, den du erwähnt hast.Daher war es für mich an dieser Stelle nicht nutzbar!

    Ich habe einen zweiten Thread in der Kategorie C++/CLI gestartet, da ich zu Beginn eh in einer falschen Kategorie war und eigentlich auch wegen einem anderen Problem (globale Objekte in .Net) nachgefragt hatte. Ich habe nur nochmal das Gerüst erwähnt, da ich im Moment noch damit rumspiele.

    Sorry...dafür!! Hoffe du akzeptierst meine Entschuldigung und hilfst mir weiter 🙄

    nn schrieb:

    Ja, sinnvoller wäre es mit einer unmanaged DLL zu beginnen und in managed Code geschriebene Teile hinzuzufügen.

    Ich finde diese Idee gut, dass man den managed und unmanged Code sogar in eigene Projekte (dadurch unterschiedliche DLLs) aufteilt. Habe im Moment den managed Code in einer eigenen Cpp/H Datei implementiert. Dadurch habe ich auch schon eine gewisse Trennung der beiden Teile!

    nn schrieb:

    Die Implementierung von deinem DLLINTERFACE ist auch Murks und geht nur mit C++ und nicht mit C.

    Japp... das sieht doch auch besser aus 🙂 Danke

    nn schrieb:

    Das Designpattern "Singleton" ist dir kein Begriff ?

    Doch... das Singleton Designpattern ist mir ein Begriff. Hatte auch am Anfang daran gedacht, dieses einzusetzen. Sinn des Singleton--Objektes ist es ja, nur einmal global angelegt zu werden. Jedoch hätte es mir denke ich bei meinem konkreten Problem (globales Objekt in .Net) auch nicht weitergeholfen. (Kann mich hier aber auch täuschen!) Habe im Netzt nun vielleicht etwas sinnvolles gefunden. Stichwort: auto_gcroot

    Mit dieser Hilfs-Schablone kann man anscheinend Managed Objekte in Unmanaged Code verwenden. Denkste, dass ich mit dem Singleton-Pattern besser fahren würde?

    Danke!!



  • [quote="skluge"]

    nn schrieb:

    Und da du ja schon selbst angemerkt hast, dass man über die googlePreview nicht den Teil einsehen kann, den du erwähnt hast

    Andere Teile des Buches kann man aber lesen ...

    skluge schrieb:

    Ich finde diese Idee gut, dass man den managed und unmanged Code sogar in eigene Projekte (dadurch unterschiedliche DLLs) aufteilt.

    Das ist eigentlich nicht der Punkt, gerade bei solchen Interfacing-Geschichten machen gemischte DLLs ja Sinn.

    Nur sollte man die so aufziehen, dass man einem unmanaged DLL-Projekt C++/CLI Codedateien hinzufügt und nur diese Dateien mit /clr übersetzt. Nicht einem Klassenbibliotheksprojekt eine unmanaged Schnittstelle hinzufügen. (Siehe Buch)

    Ein Singleton kann man auf verschiedene Weisen implementieren. Wichtig ist nur, du greifst auf dein "globales" Objekt nicht direkt zu, sondern über eine Funktion, die nachschaut, ob schon ein Objekt vorhanden ist und entweder ein Handle darauf zurückgibt, oder das Objekt vorher noch erstellt.


Anmelden zum Antworten