Managed- und Unmanaged-Code vermischen?



  • Hi,

    eigentlich programmiere ich in C# und ganz selten mal in C++, aber bisher noch nie in C++ / CLI.

    Ich denke mal dass es kein sauberer Programmierstil ist, wenn man managed und unmanaged Code vermischt, aber in meinem Fall lässt es sich nicht vermeiden. Ich verwende Funktionen aus einer C DLL die zwingend unmanaged sind.

    Jetzt ist die Frage, wie trennt man soetwas. Erstelle ich eine Unmanaged Klasse die Schnittstellen besitzt und binde diese dann in meine managed C++ Klassen ein, oder deklariere ich die Funktionen einfach außerhalb einer Klasse und rufe sie quasi global auf?

    Ich hab heute den ersten Lösungsvorschlag implementiert, leider funktioniert das ganze nicht ich bekomme folgenden Fehler:

    error C2061: syntax error : identifier '{ctor}'
    

    Sobald ich die unmanaged Klasse instanziere:

    .h Datei:

    #include "MyDll.h"
    #pragma once
    
    namespace UnmanagedCode
    {
    	class UnmanagedLayer
    	{
    		private:
    			TSXDRV_CONTROL_STRUCT *s_ptControl;
    			TSXDRV_LPT_STRUCT *s_ptLpt;   
    			bool bInitialized;
    
    		public:
    			UnmanagedLayer();
    			long Initialize();
    			long Write(unsigned long a_ulStartIndex, unsigned long a_ulLen, unsigned char* a_ucValue);
    				};
    }
    
    namespace CliLibrary 
    {
    	public ref class HardwareManager
    	{
    		private:
    			System::Collections::ArrayList^ Pathes;
    			UnmanagedCode::UnmanagedLayer* Unmanaged;
    
    		public:
    			HardwareManager();
    	};
    }
    

    .cpp-Datei

    #include "stdafx.h"
    #include "CliLibrary.h"
    
    using namespace System;
    using namespace Collections;
    using namespace Windows;
    using namespace CliLibrary;
    
    long UnmanagedCode::UnmanagedLayer::Initialize(void)
    {
    	long lError;
    
    	lError = TsxDrvControl_Init (&s_ptControl);
    	if (TSXDRV_OK != lError)
    	{
    		lError = TsxDrvLpt_Init (s_ptControl, &s_ptLpt, TSXDRV_LPT1);
    		if (TSXDRV_OK != lError)
    		{
    			lError = TsxDrvControl_Power (s_ptControl, TSXDRV_ON);
    			if(TSXDRV_OK != lError)
    			{
    				bInitialized = true;
    			}
    		}
    	}
    	return lError;
    }
    
    long UnmanagedCode::UnmanagedLayer::Write(unsigned long a_ulStartIndex, unsigned long a_ulLen, unsigned char* a_ucValue)
    {
    	long lError;
    
    	if(!bInitialized)
    	{
    		lError = -1;
    	}
    	if(a_ulStartIndex < 7)
    	{
    		lError = -2;
    	}
    	else if(a_ulLen > 8)
    	{
    		lError = -3;
    	}
    	else if((a_ulStartIndex + a_ulLen) > 8)
    	{
    		lError = -4;
    	}
    
    	if(TSXDRV_OK != lError)
    	{
    		lError = TsxDrvLpt_Group (s_ptLpt, TSXDRV_WR, a_ulStartIndex, a_ulLen, &a_ucValue);
    	}
    
    	return lError;
    }
    
    CliLibrary::HardwareManager::HardwareManager()
    {
    	Pathes = gcnew ArrayList();
    	CliLibrary::HardwareManager::Unmanaged = new UnmanagedCode::UnmanagedLayer::UnmanagedLayer();
    }
    

    Was bedeuted der Fehler und liegt das an meiner Implementierung oder an der DLL die ich verwende?

    Lg Kerberos



  • Ein Objekt instanziert man mit new Scope::Klasse und nicht mit new Scope::Klasse::Klasse 🙂

    (BTW, Membervariablen zu qualifizieren ist auch eher ungewöhnlich, Unmanaged oder auch this->Unmanaged sollten vollkommen ausreichen.)



  • Hi LordJaxom,

    erstmal Danke für deine schnelle Antwort!

    Membervariablen zu qualifizieren ist auch eher ungewöhnlich

    Entschuldige meine Unwissenheit, aber was versteht man unter "Membervariablen zu qualifizieren".

    Des Weiteren hab ich noch eine Frage:

    Wenn ich die Klasse HardwareManager wie folgt instanzieren möchte

    CliLibrary::HardwareManager hwm = gcnew CliLibrary::HardwareManager();
    

    dann bekomme ich folgende Fehlermeldung:

    error C3673: 'CliLibrary::HardwareManager' : class does not have a copy-constructor
    

    Was ist ein Copy-Constructor

    Lg Chriss



  • kerberos schrieb:

    Entschuldige meine Unwissenheit, aber was versteht man unter "Membervariablen zu qualifizieren".

    class X
    {
        int a;
    
        X();
    };
    
    X::X()
    {
        a = 12; // "normaler" Zugriff auf Membervariable
        this->a = 12; // auch noch gebräuchlich, aber schon ungewöhnlicher
        ::X::a = 12; // wozu? davon ab, dass ich garnicht weiss, ob das so compiliert.
        // this->::X::a wäre vollqualifiziert
    }
    

    Des Weiteren hab ich noch eine Frage:

    Wenn ich die Klasse HardwareManager wie folgt instanzieren möchte

    CliLibrary::HardwareManager hwm = gcnew CliLibrary::HardwareManager();
    

    dann bekomme ich folgende Fehlermeldung:

    error C3673: 'CliLibrary::HardwareManager' : class does not have a copy-constructor
    

    Du versuchst auch, einem Objekt vom Typ Hardwaremanager ein referenzgezähltes Handle auf ein Objekt vom Typ Hardwaremanager zuzuweisen. Wenn, dann so:

    CliLibrary::HardwareManager^ hwm = gcnew CliLibrary::HardwareManager()
    

    Was ist ein Copy-Constructor

    Ein Konstruktor, der ein Objekt desselben Typs als einzigen Parameter erwartet, um daraus eine Kopie zu erstellen, die dann in dem Objekt, welches der Konstruktor erstellt, gespeichert wird.


Anmelden zum Antworten