Verständnissfrage zu klassenbibliothek



  • Hi

    Ich habe ein kleines Programm geschrieben, als exe-datei kompiliert funktioniert es super.
    kann ich daraus auch eine DLL machen die ich von einen anderen programm aufrufe mit dem ich dann auch die member verwenden kann?

    ich habe es mal ganz mutig einfach versucht, trotz mut hat es nicht funktioniert. er beschwerte sich einfach nur dauert das die namespace nicht gehen und der :: operator fand er auch doof (mit er ist der compiler gemeint).

    ich glaube ich hab da was falschverstanden (glaube in diesen fall, bin sicher) 🙂

    gruß
    LoM



  • Wenn du eine Klassen Bibliothek erstellst, kannst du die dll in andere Projekte einfügen, indem du im Solutionmanager rechtsklick auf das Projekt, an das du die DLL anfügen möchtest, ausführst und dann bei Referenzen auf Referenz hinzufügen drückst. Dann gehst du auf den Durchsuchen-Tab und fügst die dll ein.

    Eine Andere Möglichkeit ist, dass du deinem Arbeitsbereich ein neues Projekt hinzufügst und da die Einstellung Klassenbibliothek wählst, dann gehst du bei Referenz hinzufügen auf Projekt und wählst die Bibliothek auswählst. Das hat den Vorteil, dass du beim Debuggen die Zeile angezeigt bekommst 😉

    Hier mal ein Beispiel für eine Klasse in der Bibliothek

    #pragma once
    using namespace System;
    namespace System{//Um in den System Namespace einzufügen
        namespace DeinNamespace{//Der Name deines Namespaces
            public ref class DeineKlasse{
                public:int irgendnevariable;
            };
        }
    }
    

    Im Programm oder einer anderen Dll kannst du dann DeineKlasse per

    System::DeinNamespace::DeineKlasse^ irgendwas=gcnew System::DeinNamespace::DeineKlasse();
    

    Wenn du se nicht im System Namespace hast musst du :: eingeben ohne etwas davor



  • Intuitivwürde ich sagen:

    Finger weg vom Namespace System

    @xlomx geht nicht ist keine Fehlerbeschreibung



  • Das hab ich erstmal verstanden, bloß geht es immernoch nicht 😞

    @Knuddelbaer
    hab ein schon ein wenig im Forum gelesen deine tips sind nützlich, doch auch oft leicht beleidigend 🙂
    recht hast du aber trotzdem.

    deswegen hier die antwort des compilers auf meine hoffendlich nette bitte das "programm" zu kompilieren.

    test.h(34) : error C3083: "Windows": Das Symbol links neben "::" muss ein Typ sein.
    test.h(34) : error C3083: "Forms": Das Symbol links neben "::" muss ein Typ sein.
    test.h(34) : error C2039: 'Timer': Ist kein Element von 'System'
    test.h(34) : error C2143: Syntaxfehler: Es fehlt ';' vor '^'
    test.h(34) : error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    test.h(34) : error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    test.h(261) : error C2143: Syntaxfehler: Es fehlt ';' vor '}'
    test.h(16) : error C2065: 'Timer': nichtdeklarierter Bezeichner
    test.h(16) : error C3083: "Windows": Das Symbol links neben "::" muss ein Typ sein.
    test.h(16) : error C3083: "Forms": Das Symbol links neben "::" muss ein Typ sein.
    test.h(16) : error C2039: 'Timer': Ist kein Element von 'System'
    test.h(16) : error C2061: Syntaxfehler: Bezeichner 'Timer'
    test.h(17) : error C2227: Links von "->Interval" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.
            Typ ist ''unknown-type''
    test.h(18) : error C2227: Links von "->Tick" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.
            Typ ist ''unknown-type''
    test.h(67) : error C2227: Links von "->Enabled" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.
            Typ ist ''unknown-type''
    test.h(71) : error C2227: Links von "->Enabled" muss sich ein Zeiger auf Klassen-/Struktur-/Union-/generischen Typ befinden.
            Typ ist ''unknown-type''
    test.h(222) : error C3083: "Windows": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C3083: "Forms": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C3083: "MessageBox": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C2039: 'Show': Ist kein Element von 'System'
    test.h(222) : error C2653: 'Windows': Keine Klasse oder Namespace
    test.h(222) : error C2065: 'OK': nichtdeklarierter Bezeichner
    test.h(222) : error C2653: 'Windows': Keine Klasse oder Namespace
    test.h(222) : error C2065: 'Error': nichtdeklarierter Bezeichner
    test.h(222) : error C3861: "Show": Bezeichner wurde nicht gefunden.
    test - 25 Fehler, 0 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    

    wieder dieser :: operator der beklagt wird, kann ich ihn in Klassenbilblidings nicht verwenden? wenn nicht gibt es eine alternative?
    gruß
    LoM



  • Wie wäre es mit ein bisschen Quellcode?



  • Die Meldungen weisen auf unbekannte Namensräume hin.

    Du kannst mit using namespace diese bekannt machen oder musst sie explizit angeben.

    Ohne den passenden Quellcode kann man da aber nicht viel helfen.

    Beispiel:

    test.h(222) : error C3083: "Windows": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C3083: "Forms": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C3083: "MessageBox": Das Symbol links neben "::" muss ein Typ sein.
    test.h(222) : error C2039: 'Show': Ist kein Element von 'System'
    test.h(222) : error C2653: 'Windows': Keine Klasse oder Namespace
    test.h(222) : error C2065: 'OK': nichtdeklarierter Bezeichner

    Es könnte heissen:

    System::Windows::Forms
    System::Windows::Forms::MessageBox::Show
    System::Windows::Forms::DialogResult::OK
    

    oder

    using namespace System;
    using namespace System::Windows;
    using namespace System::Windows::Forms;
    
    MessageBox::Show()
    DialogResult::OK
    

    Wenn dann immernoch die Typen unbekannt sind ('Timer': Ist kein Element von 'System') , prüfe ob Du auch die Verweise gesetzt hast. (Ohne die DLLs bzw. Verweise einzubinden kennt er die Namensräume nicht).

    An meinem Auftritt arbeite ich, versprochen. (Wobei es IMHO manchmal nicht schaden kann mal etwas direkter zu sein)



  • die ersten fehler beziehen sich auf

    private: System::Windows::Forms::Timer^  Timer;
    

    der ganze quellcode wird etwas viel sein, außerdem ist er mir noch etwas peinlich. ich schreibe noch nicht lange Objekt Orientiert.

    obwohl vieleicht ist es besser wenn ihr gleich meckert, dann lerne ich schneller.

    #pragma once
    
    using namespace System;
    
    namespace SerialGerät3 {
    
    	public ref class SerialGerät3
    		{
    	public:
    		SerialGerät3(void)
    		{
    			unvollDaten="";
    			Daten=gcnew array<double>(0);
    			Timer = (gcnew System::Windows::Forms::Timer());
    			Timer->Interval = 100;
    			Timer->Tick += gcnew System::EventHandler(this, &SerialGerät3::Timer_Tick);
    		}
    
    	private:
    		int Spannung;
    		array<int>^ MessSpannung;
    		int Range;
    		array<int>^ MessRange;
    		System::IO::Ports::SerialPort^  srp;
    		String^ Comport;
    		array<double>^ Daten;
    		array<double>^ Zeit;
    		double MessZeit;
    		String^ unvollDaten;
    		String^ Mode;
    		bool offen;
    		private: System::Windows::Forms::Timer^  Timer;
    
    	public:
    		void Open() {
    			offen=true;
    		}
    		void COMOpen(String^ Comport){
    			srp=gcnew System::IO::Ports::SerialPort(Comport,9600,System::IO::Ports::Parity::None,8,System::IO::Ports::StopBits::One);
    			srp->ReadTimeout::set(1000);
    			this->srp->DataReceived += gcnew System::IO::Ports::SerialDataReceivedEventHandler(this, &SerialGerät3::srp_DataReceived);
    			srp->Open();
    			Open();
    			StromMessen();
    			MessungStoppen();
    			Close();
    		}
    		void Close() {
    			offen=false;
    		}
    		bool Highohm() {
    			Mode="LowOhm";
    			return(Senden("RXH"));
    		}
    		bool StromMessen() {
    			Mode="Strom";
    			return(Senden("IX"));
    		}
    		bool LowOhmMessen() {
    			Mode="LowOhm";
    			return(Senden("RXL"));
    		}
    		bool MessungStarten() {
    			MessZeit=0;
    			Timer->Enabled=true;
    			return(Senden("STA"));
    		}
    		bool MessungStoppen() {
    			Timer->Enabled=false;
    			return(Senden("STP"));
    		}
    		bool VierPolMessung() {
    			return(Senden("WIMO_2"));
    		}
    		bool ZweiPolMessung() {
    			return(Senden("WIMO_4"));
    		}
    		bool Zero() {
    			return(Senden("ZERO"));
    		}
    		bool SpannungEin() {
    			return(Senden("VMON"));
    		}
    		bool SetSpannung(int u) {
    			Spannung=u;
    			if ((u<=500) && (u>0)) {
    				switch (u) {
    					case 10:
    						return(Senden("VM10"));
    						break;
    					case 100:
    						return(Senden("VM100"));
    						break;
    					case 500:
    						return(Senden("VM500"));
    					break;
    					default:
    						String^ Üspannung;
    						Üspannung=String::Format("VAR{0,3:D3}",Spannung);
    						return(Senden(Üspannung));
    						break;
    				}
    			}
    			return(false);
    		}
    		bool SpannungAus() {
    			return(Senden("VMOF"));
    		}
    		bool SpannungVar() {
    			return(Senden("VAR"));
    		}
    		bool RangeManuel() {
    			return(Senden("MAN"));
    		}
    		bool RangeAuto() {
    			return(Senden("AUTO"));
    		}
    		bool RangeAutoDelay(int delay) {
    			if ((delay>=0)&&(delay<=30)) {
    				String^ Sdelay;
    				Sdelay=String::Format("ADELAY_{0,2:D2}",delay);
    				return(Senden(Sdelay));
    			}
    			return(false);
    		}
    		bool RangeRange(int range) {
    			String^ Srange;
    			Srange=String::Format("RG_{0}",range);
    			return(Senden(Srange));
    		}
    		bool RangeLimits(int unten, int oben) {
    			if ((unten>0)&&(unten<=7)&&(oben>0)&&(oben<=7)&&(oben>=unten)) {
    				String^ Limits;
    				Limits=String::Format("RGL_{0}_{1}",unten,oben);
    				return(Senden(Limits));
    			}
    			return(false);
    		}		
    
    //--------------Daten Empfangen----------------------
    private: System::Void srp_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e) {
    				 String^ S=gcnew String("");
    				 S=srp->ReadExisting();
    				 unvollDaten=unvollDaten+S;
    				 int KlammaZu;
    				 int KlammaAuf;
    				 int x;
    //---------------Acknolage und notack entfernen-----------------------------------------
    				 String^ scheis=gcnew String(0x06,1);
    				 unvollDaten=unvollDaten->Replace(scheis,"");
    				 scheis=gcnew String(0x15,1);
    				 unvollDaten=unvollDaten->Replace(scheis,"");
    				 do {
    					 KlammaAuf=unvollDaten->IndexOf("(");
    					 if (KlammaAuf==-1) {
    						 unvollDaten="";
    						 return;
    					 }
    					 unvollDaten=unvollDaten->Substring(KlammaAuf);
    					 KlammaAuf=unvollDaten->IndexOf("(");
    					 KlammaZu=unvollDaten->IndexOf(")");
    					 if ((KlammaZu>=0) && (KlammaAuf>=0)) {
    //-----------------------------Abfragen ob ein Kompletter Datensatz übermittelt wurde.
    						 if ((KlammaZu-KlammaAuf)>4) {
    							 String^ FloatZahl;
    							 x=unvollDaten->IndexOf("Overrange");
    							 if ((x<0) || (x>KlammaZu)) {
    								 FloatZahl=unvollDaten->Substring(unvollDaten->IndexOf("E")-9,13);
    //-----------------------------Freizeichen aus String FloatZahl entfernen----------------------
    								 FloatZahl=FloatZahl->Replace(" ","");
    								 FloatZahl=FloatZahl->Replace("*","-");
    								 FloatZahl=FloatZahl->Replace(">","");
    								 FloatZahl=FloatZahl->Replace("(","");
    //-----------------------------Daten in Array schreiben.------------------------------
    								 try {
    //-----------------------------Arrays für Messdaten erweitern-------------------------
    								 int DatenLänge=Daten->Length;
    								 Array::Resize(Zeit,DatenLänge+1);
    								 Array::Resize(MessRange,DatenLänge+1);
    								 Array::Resize(MessSpannung,DatenLänge+1);
    								 Array::Resize(Daten,DatenLänge+1);
    
    								 Daten[DatenLänge]=Convert::ToDouble(FloatZahl);	//Der zahlenwert
    								 Zeit[DatenLänge]=MessZeit*0.1;						//Die Messzeit
    								 x=unvollDaten->IndexOf("R");
    								 MessRange[DatenLänge]=Convert::ToInt32(unvollDaten->Substring(x+1,1));	//Der Range
    								 x=unvollDaten->IndexOf("V");
    								 String^ UnterSpannung=unvollDaten->Substring(x+1,3);
    								 UnterSpannung=UnterSpannung->Replace("-","0");
    								 MessSpannung[DatenLänge]=Convert::ToInt32(UnterSpannung);		//Die Spannung
    								 }
    								 catch (Exception^ ) {
    								 }
    							 }
    						 }
    						 unvollDaten=unvollDaten->Remove(KlammaAuf,KlammaZu-KlammaAuf+1);
    					 }
    					 KlammaAuf=unvollDaten->IndexOf("(");
    					 KlammaZu=unvollDaten->IndexOf(")");
    				 } while ((KlammaZu>=0) && (KlammaAuf>=0)) ;
    				 if ((KlammaAuf>=0) && (KlammaZu>=0))
    					 unvollDaten="";
    			 }	
    
    //--------------Daten Senden-------------------------
    private: bool Senden(String^ Befehl) {
    			if (offen) {
    				Befehl=Befehl+"\r\n";
    				srp->Write(Befehl);
    				try {
    /*				char akn;
    				akn=srp->ReadByte();
    				if (akn==06)
    */				return(true);
    //			return(false);
    				}
    				catch (Exception^ ) {
    					Close();
    					System::Windows::Forms::MessageBox::Show("Kein Kontakt zu SerialGerät","TimeOut",Windows::Forms::MessageBoxButtons::OK,Windows::Forms::MessageBoxIcon::Error);
    				}
    			}
    			return(false);
    		}	
    
    public:	array<double>^ EmpfangeneDaten() {
    			return(Daten);
    			}
    			void EmpfangeneDatenLöschen() {
    				Array::Clear(Daten,0,Daten->Length);
    				Array::Resize(Daten,0);
    				MessZeit=0;
    				return;
    			}	
    
    			String^ DatenEinheit() {
    				if (Mode=="Strom")
    					return("A");
    				if (Mode=="LowOhm")
    					return("Ohm");
    				return("Mode Fehler");
    			}
    			array<double>^ MessZeitArray() {
    				return(Zeit);
    			}
    			array<int>^ MessSpannungsArray() {
    				return(MessSpannung);
    			}
    			array<int>^ MessRangeArray() {
    				return(MessRange);
    			}	
    
    private: System::Void Timer_Tick(System::Object^  sender, System::EventArgs^  e) {
    				 MessZeit++;
    			}
    		 }
    
    };
    

    Das daten empfangen-teil bitte ignorieren, das gefällt mir auch überhaupt nicht. ich mage keine sich ständig verändernen strings wo man zahlen rauslesen muss 😞 und einfacher haben die einen es auch nicht gemacht mit den char/wchar zeug. ansonsten meckert ruhig 🙂

    @knuddlbaer

    Wenn dann immernoch die Typen unbekannt sind ('Timer': Ist kein Element von 'System') , prüfe ob Du auch die Verweise gesetzt hast. (Ohne die DLLs bzw. Verweise einzubinden kennt er die Namensräume nicht)

    ist interesant, das könnte der fehler sein. wenn ich eine windows form erstelle bindet er die Dlls gleich mit ein? sozusagen automatisch. was muss ich machen um das per hand zu machen?

    grüße
    LoM



  • Beim ersten überfliegen schaut das mit den Namensräumen gut aus.
    Die DLLs werden normal automatisch eingebunden wenn Du eine WinForm machst.

    Geh mal in die Projekteigenschaften und schau mal ob die Verweise System, System::Drawing und System::Windows::Forms vorhanden sind:

    http://www.rothmichael.de/cpp/verweise.png

    Und versuche mal den Namensraum nicht den gleichen Namen zu geben wie den Elementen innerhalb des Namensraumes:

    namespace SerialGerät3 { 
    
        public ref class SerialGerät3 
            {
    

    SerialGerät3::SerialGerät3 könnte mal der Konstruktor sein, mal der Namensraum mit dem Typ SerialGerät3. Wenn es den Compiler nicht verwirrt, den Anwender der Klasse sicherlich.



  • knuddelbaer, das mit den verweisen hat funktioniert. Danke dir.

    das steht in meinen eigendlich guten buch nciht drin, oder ich habe es nicht gefunden 🙂
    das mit den namensraum und den konstruktornamen ändere ich sofort.

    achso fals einer frag ich habe das buch: "einstieg in visual c++ 2005" von Andre Willms.

    ich kenne mich ich würde es wissen wollen, wenn einer ein buch erwähnt 🙂





  • genau das, ich finde es ganz gut.

    wie findest du es?



  • Ich find es recht einfach bei Amazon 😃

    Ich habe das Buch nicht, wollte aber mal nachfragen. Die Information kann man ggf. mal weitergeben wenn jemand nach einem Buch fragt.

    Meinen Quereinstieg hab ich mit

    Pro Visual C++/CLI and the .NET 2.0 Platform | ISBN: 1590596404

    und der MSDN hinter mir. Es gibt aber immer neues zu lernen und Bücher sind dabei eine feine Sache.



  • Das Buch ist vorgemerkt 🙂 danke

    ich habe noch eine frage zur bilbiothek. Ich habe sie jetzt eingebunden und es funktioniert auch soweit. nur geht das mit den IntelliSense nicht. wirklich schlimm ist es nun nicht, es wäre nur eine nette zugabe.

    achso ich habe die DLL unter den eigenschaften eingebunden, ist das ok? oder gibt es einen anderen vieleicht besseren weg.



  • Das ist das selbe wie mit Rechtsklick->Verweise, da die Seite im Selben Menü ist



  • RrobthaR

    danke für deinen code-schnipsel am anfang der hat super geholfen, da konnte ich genau dran erkennen wie ich eine DLL aufbauen muss, danke.



  • Der Vollständigkeitshalber noch drei anmerkungen:

    a) Namespace System solltest Du nicht verwenden um dort eigene Klassen zu Plazieren

    b) :: verwendet man nicht, wenn der eigene Namensraum nicht in System liegt sondern wenn man Symbole im Globalen Namensraum ansprechen möchte. (Wenn man beim Beispiel System einfach weglässt, steht MyNamespace im Globalen Namensraum*)

    c) Alles was man von der DLL wo anderst verwenden will muss public sein.

    Kleinigkeiten die einen aber zu einem späteren Zeitpunkt Ärger machen können.

    Wenn man z.B. using namespace System::Windows::Forms macht, steht alles, was in diesem Namensraum eingeschlossen wurde im Globalen Namensraum. Auch wirst Du :: am Anfang benötigen, wenn Du in einem Namensraum bist, das ein gleiches Symbol kenn wie der globale. Wenn Du dann das Globale Symbol meinst, >>muss<< :: davor


Anmelden zum Antworten