Problem: Illegal Call of non static member funktion
-
Moin ...
Seit Tagen ärgere ich mich nun mit dieser Fehlermeldung rum. Brauche hier wiedermal eure Hilfe. Hier zunächst ein Ausschnitt aus der Form1:
#pragma once namespace IPSender { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); } public: ~Form1() { if (components) { delete components; } } /**************************************************************************************************************/ public: void textbox1ändern (String^ text) {textBox1->Text = "textbox1ändern"} /**************************************************************************************************************/ private: System::Windows::Forms::Button^ button1; private: System::Windows::Forms::Button^ button2; private: System::Windows::Forms::NotifyIcon^ notifyIcon1; public: System::Windows::Forms::TextBox^ textBox1; private: System::Windows::Forms::Button^ button3; public: System::Windows::Forms::Label^ label1; public: System::Windows::Forms::TextBox^ textBox2; private: System::ComponentModel::IContainer^ components; ... ... ...
Nun möchte ich aus einer FUNKTION.CPP die TextBox1 ansprechen und darin einen Text ausgeben:
... ... /* IP SENDER starten */ void start (void) { Form1::textbox1ändern ("textbox1ändern"); ... ... ... }
Hierbei erhalte ich dann die genannte Fehlermeldung. Also versuche ich die Memberfunktion als static zu deklarieren:
/**************************************************************************************************************/ public: static void textbox1ändern (String^ text) {textBox1->Text = "textbox1ändern"} /**************************************************************************************************************/
error C2228: left of '.Text' must have class/struct/union
Nun habe ich natürlich schon ewig nach einer Lösung gesucht und herausgefunden das statische Memberfunktionen keinen this zeiger besitzen. Wie spreche ich die TextBox1 hier nun an ohne einen this Zeiger?
-
1. Falsches Forum; korrekt wäre C++/CLI
2. Du musst eine Instanz der Form1 erzeugen und deine Methode NICHT statisch machen.void start (void) { Form1^ form = gcnew Form1(); form->textbox1ändern ("textbox1ändern"); ... ... ... }
Simon
-
Sorry ... dann bitte verschieben.
Das war dann also die Lösung. Und ich hatte mich schon mit Instanzen beschäftigt.
Nun siehts wie folgt aus:
/*************************************** Ab hier Öffentliche Member Funktion *********************************/ public: void Form1::textbox1ändern (String ^text) {textBox1->AppendText (text);} /**************************************************************************************************************/
/* IP SENDER starten */ void start (void) { /* Instanz erstellen */ Form1^ form = gcnew Form1(); form->textbox1ändern ("textbox1ändern");
Der Fehler ist nun verschwunden. Beim starten erscheint allerdings der angegebene String nicht in der Textbox. Woran könnte das liegen?
-
Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum WinAPI in das Forum C++/CLI mit .NET verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Es liegt daran, dass du dich scheinbar noch nicht genug mit Instanzen beschäftigt hast.
/* IP SENDER starten */ void start (void) { /* Instanz erstellen */ Form1^ form = gcnew Form1(); form->textbox1ändern ("textbox1ändern");
Du rufst die Funktion auf, wie es erlaubt und gedacht ist, doch die Instanz, auf welcher du die Funktion benutzt, ist irgendeine, welche du neu erstellst und nachher nie mehr brauchst. Du musst sie für die Form aufrufen, welche du nachher verwendest sonst nützt das natürlich alles nix
-
Ich denke, Du hast schon eine Instanz von Form1 (nämlich, die die im Main erzeugt wird).
Die Form1 die Du eben so in start(..) erzeugt hast, wird noch gar nicht angezeigt. Mit form->Show(); kannst Du sie anzeigen lassen.
Ich denke jedoch, das ist nicht das was sDu möchtest. Ich vermute Du möchtest viel eher die schon existierende Instanz benutzen.
Zeig mal ein wenig mehr code: Wo wird start aufgerufen?
Simon
-
mmh ... und wie könnte das dann aussehen?
-
theta schrieb:
Ich denke, Du hast schon eine Instanz von Form1 (nämlich, die die im Main erzeugt wird).
Die Form1 die Du eben so in start(..) erzeugt hast, wird noch gar nicht angezeigt. Mit form->Show(); kannst Du sie anzeigen lassen.
Ich denke jedoch, das ist nicht das was sDu möchtest. Ich vermute Du möchtest viel eher die schon existierende Instanz benutzen.
Zeig mal ein wenig mehr code: Wo wird start aufgerufen?
Simon
Da haste recht Simon. Das war nicht das was ich wollte.
Start () wird durch ein Event in der Form1 aufgerufen. Sämmtliche Funktionen befinden sich in der Funktion.cpp.
-
Dann könntest Du das so machen:
void start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); ... ... ... }
// start(..) wird dann so aufgerufen: // this muss natürlich Form1^ sein. start(this);
Könnte start() nicht auch gerade eine Methode von Form1 sein?
Simon
-
Hauptprogramm.cpp
#include "stdafx.h" #include "Form1.h" using namespace IPSender; int main(array<System::String ^> ^args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew Form1()); return 0; }
stdafx.h
#pragma once #include <windows.h> #include <iostream> #include <string.h> #include <wininet.h> #include <vcclr.h> #include <stdlib.h> #include <process.h> #pragma comment(lib,"winmm.lib") #pragma comment (lib,"ws2_32.lib") #pragma comment (lib,"winInet.lib") #pragma comment ("System.dll") #pragma comment ("WinInet.dll") #pragma comment ("mapi32.dll") #pragma comment ("mscorlib.dll") #pragma comment ("kernel32.dll") // TODO: reference additional headers your program requires here // #include "eigeneFunktionen.h"
eigeneFunktionen.h
extern char localhost [16] = "127.0.0.1"; extern char meinedyndnsIP [16] = {0}; extern char übergebeneIP [16] = "127.0.0.1"; extern char sounddatei [] = "Wolf.wav"; extern char dummy; extern int x; extern char hostnamelokal [255], hostname[255]; extern bool lokaleIPfinden (); extern void ping (char*); extern void start (Form1^ form); extern void sound (void); extern char* umwandeln(System::String^ str); //extern void eIPfinden(char *);
eigeneFunktionen.cpp
/*********************************************************************************/ /***************************** eigene Funktionen *********************************/ /*********************************************************************************/ #pragma once #include "stdafx.h" #include "Form1.h" using namespace IPSender; #define neuezeile "\n\n"; char dummy; int x; char hostnamelokal [255], hostname[255]; bool verbunden = FALSE; char lokaleIP [16] = {0}; char externeIP [16] = {0}; unsigned int nThreadAddress; ... ... /* IP starten */ void start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); //_beginthreadex(0, 0, &sound, 0, 0, &nThreadAddress); ... ... ...
Nun erhalte ich folgende Fehler:
Error 6 error C2065: 'Form1' : undeclared identifier c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 21 Error 7 error C2065: 'form' : undeclared identifier c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 21 Error 8 error C2182: 'start' : illegal use of type 'void' c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 21 Error 9 fatal error C1903: unable to recover from previous error(s); stopping compilation c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 21
Ich blicke nicht mehr durch. Echt nicht.
-
Ich blicke nicht mehr durch. Echt nicht.
Ich weiss..
Nur nicht aufgeben...
Die Fehler kommen daher, dass der Typ Form1 unbekannt ist. Es wird ein include benötigt.
Ausserdem fällt mir auf, dass C / C++ und C++/CLI wild gemischt werden. Ich halte das für falsch und nicht sinnvoll. Ausserdem ist es so extrem schwierig die Sprache oder Programmieren zu lernen. Die möglichen Fehlerquellen sind massiv grösser beim mischen dieser drei Sprachen.
Daher empfehle ich bleibe bei einer Sprache. Ausserdem würde es auch einfachere Sprachen als die oben genannten geben...Simon
-
Danke Simon ...
-
es ist mir fast peinlich ...
nun habe ich versucht eure Tips umzusetzen und stehe vor einem weiteren Problem:
stdafx.h
#pragma once #include <windows.h> #include <iostream> #include <string.h> #include <wininet.h> #include <vcclr.h> #include <stdlib.h> #include <process.h> #pragma comment(lib,"winmm.lib") #pragma comment (lib,"ws2_32.lib") #pragma comment (lib,"winInet.lib") #pragma comment ("System.dll") #pragma comment ("WinInet.dll") #pragma comment ("mapi32.dll") #pragma comment ("mscorlib.dll") #pragma comment ("kernel32.dll") // TODO: reference additional headers your program requires here // #include "eigeneFunktionen.h"
eigeneFunktionen.h
#pragma once #include "stdafx.h" #include "Form1.h" ... ... void start ( Form1^ form );
Form1.h
#include "stdafx.h" #include "eigeneFunktionen.h" ... ... ... private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { start(); }
EigeneFunktionen.cpp
... ... void start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); lokaleIPfinden ();
Jetzt erhalte ich folgenden Fehler:
Error 6 error C3861: 'start': identifier not found f:\ipsender\ipsender\Form1.h 239
Soweit glaube ich das zu verstehen: Form1 wird "includiert" bevor die Funktion start() definiert ist ?! Versuche ich nun hier abhilfe zu schaffen, indem ich im Hauptprogramm erst eigeneFunktionen.h einfüge, und anschliessend die Form1 passiert folgendes:
Error 6 error C2871: 'IPSender' : a namespace with this name does not exist f:\ipsender\ipsender\eigeneFunktionen.h 8 Error 7 error C2065: 'Form1' : undeclared identifier f:\ipsender\ipsender\eigeneFunktionen.h 27 Error 8 error C2065: 'form' : undeclared identifier f:\ipsender\ipsender\eigeneFunktionen.h 27 Error 9 error C2182: 'start' : illegal use of type 'void' f:\ipsender\ipsender\eigeneFunktionen.h 27 Error 10 fatal error C1903: unable to recover from previous error(s); stopping compilation f:\ipsender\ipsender\eigeneFunktionen.h 27
Mit meinen geringen Wissen auch nachzuvollziehen, da bspw. der Namespace IPSender ja noch nicht existiert.
Wie würde ich hier sinnvoll weiter kommen?
-
theta schrieb:
Dann könntest Du das so machen:
void start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); ... ... ... }
// start(..) wird dann so aufgerufen: // this muss natürlich Form1^ sein. start(this);
Könnte start() nicht auch gerade eine Methode von Form1 sein?
Simon
Habe es nun irgendwie geschafft das ganze auf folgende Fehlermeldung zu reduzieren:
Error 1 error C2061: syntax error : identifier 'Form1' c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 34
-
#include "Form1.h"
-
Danke für den Tip. Nur habe ich die Form1 bereits in sämmtliche Sources eingefügt. Ich habe irgendwie das gefühl dass die Reihenfolge der Includes nicht stimmt. Aber hier habe ich bereits alle möglichen Varianten versucht.
Es scheint als seien Form1.h und Funktionen.h einfach zu abhängig voneinander. Etwas mache ich grundsätzlich falsch.
Schreibt man eigentlich sämmtliche Includes in die "stdafx.h" um soetwas zu vermeiden?
-
Könnte das Dein Problem lösen?
http://www.rb-softarticle.com/Hauptprog.rar
Du musst auch Form1.h in der Form2.cpp includen, nicht in der Form2.h...
-
Ein wenig hat mich das weitergebracht. Ich hatte einfach alles "wild" durcheinander gewürfelt - durch das ganze hin und her. Somit habe ich das schlimmste überwunden - dachte ich. Kompilieren lässt es sich nun ohne Fehler.
Nur bin ich leider wieder - wie es scheint - einige Schritte rückwärts gegangen. Hänge nun wieder da - wo ich irgendwann einmal aufgehört habe. Bei dem verstehen von Instanzen.
Das aufrufen der Start-Funktion als Event klappt nun ohne Probleme:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) /* <-- Ab hier IP Senden */ { eigeneFunktionen^ funkinstanz = gcnew eigeneFunktionen(); funkinstanz->start(); }
Nur in der Start Funktion selber scheine ich immer noch den gleichen Fehler zu machen wie zuvor (neue Instanz von Form1):
void eigeneFunktionen::start () { Form1^ form = gcnew Form1(); form->textbox1ändern ("textbox1ändern"); form->Show(); //_beginthreadex(0, 0, &sound, 0, 0, &nThreadAddress);
Nur will ich ja die bereits bestehende Instanz von Form1 nutzen. Den Voschlag von theta weiss ich leider nicht umzusetzen:
void start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); ... ... ... }
// start(..) wird dann so aufgerufen: // this muss natürlich Form1^ sein. start(this);
-
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) /* <-- Ab hier IP Senden */ { eigeneFunktionen^ funkinstanz = gcnew eigeneFunktionen(); funkinstanz->start(this); }
void eigeneFunktionen::start (Form1^ form) { form->textbox1ändern ("textbox1ändern"); }
Simon
-
Mensch Simon ... soweit hatte ich deinen Tip beim ersten mal schon verstanden. Nur hatte ich bereits da das Problem, dass der Bezeichner Form1 anschließend in der Funktionen.h nicht bekannt zu seien schien.
Error 1 error C2061: syntax error : identifier 'Form1' c:\users\jens\desktop\downloads\c++ lernen\c++\projekte\ipsender\ipsender\eigeneFunktionen.h 26
Wie soll denn der Prototyp von Start aussehen? Momentan sieht er bei mir auch so aus - was mir aber nicht richtig erscheint:
void start (Form1^ form);
Hierbei dann folgender Fehler im Event der Form1:
Error 2 error C2660: 'IPSender::eigeneFunktionen::start' : function does not take 1 arguments
Ich übergebe doch - durch deinen Code - aus dem Event der Form1 den this-Zeiger an die Funktion Start - oder nicht? Verwende ich im Prototypen als Parameter "this" bekomme ich diese Meldung:
Error 1 error C2059: syntax error : 'this'