PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MS C++ Express: Globale Variablen?


aths
2011-11-23, 12:37:57
Meine C/C++-Erfahrungen sind etliche Jahre alt und beziehen sich nur auf Konsolenanwendungen.

Ich spiele gerade mit einer Windows-Form-Anwendung in Microsoft Visual C++ 2010 Express rum, die Test-Anwendung nenne ich test_vis. In der text_vis.cpp habe ich ganz oben eine Variable deklariert:

int global_i;

Danach folgen die Includes:

#include "stdafx.h"
#include "Form1.h"

using namespace test_vis;

In der Form1.h, wo die IDE automatisch die Methoden anlegt um zum Beispiel auf ein Timer-Event zu reagieren, habe ich in die erste Zeile eingefügt:

extern int global_i;

Weder in der Form1.h, noch in der test_vis.cpp kann ich aber auf global_i zugreifen:

int main(array<System::String ^> ^args)
{ // global_i=0;

// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);

// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}

Sofern ich die Zuweisung auf global_i nicht auskommentiere, kompiliert er das Programm nicht. Wo liegt der Fehler?

Ectoplasma
2011-11-23, 13:28:24
Wäre schön, wenn du mal die Fehlermeldung posten würdest. Ansonsten kann ich mir irgendeinen Konflikt mit Namensräumen vorstellen.

aths
2011-11-23, 13:52:11
Die Fehlermeldung ist, dass die Variable nicht deklariert sei:


1>------ Build started: Project: test_vis, Configuration: Debug Win32 ------
1> test_vis.cpp
1>test_vis.obj : error LNK2020: unresolved token (0A00000B) "int global_i" (?global_i@@$$Q3HA)
1>test_vis.obj : error LNK2001: unresolved external symbol "int global_i" (?global_i@@$$Q3HA)
1>C:\Users\TGT\Documents\Visual Studio 2010\Projects\test_vis\Debug\test_vis.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========




edit: Oder sehe ich das zu kompliziert? Wäre es sinniger, Form1 als Property einen Integer zu geben? Form1 dürfte ja nur ein mal instanziert sein und ist die ganze Zeit aktiv. Hätte ich dann nicht eine quasi-globale Variable?

Exxtreme
2011-11-23, 14:04:18
Soviel ich weiss definiert das Schlüsselwort extern, dass sich eine globale Variable in einer anderen Unit/CPP-Datei befindet und man kann mit diesem Schlüsselwort darauf zugreifen. Ist diese Variable nicht definiert dann schlägt der Versuch fehl.

Lass das Schlüsselwort extern weg und versuche es dann.

aths
2011-11-23, 14:27:23
Das ist noch nicht das Problem, da ich bereits in test_vis.cpp in der main-Funktion nicht auf die global deklarierte Variable zugreifen kann. In der Form1.h kann ich es auch nicht, aber zunächst würde ich gerne wenigstens in der main-Funktion das können.

Markus89
2011-11-23, 15:32:05
Deklariere die Variable mal unter den includes.

aths
2011-11-23, 17:29:57
Das geht. Danke.

Tiamat
2011-11-23, 17:48:43
Das ist doch aber auch total abwägig.
Die globale Variable wird doch im Header und nicht in ner .cpp angelegt.
Dann klappts auch mit extern :wink:

Coda
2011-11-23, 21:50:02
Das geht. Danke.
Deklaration mit extern in den Header, normale Deklaration in ein Source-File ist der korrekte Weg. Das sagt dir auch der Linker.

Wenn du eine Deklaration ohne extern in den Header machst müsstest du eigentlich eine Fehlermeldung bekommen wenn zwei Sources den Header benutzen.

Ach so: Ja, natürlich unter den Includes, sorry.

Gast
2011-12-04, 03:55:54
int main(array<System::String ^> ^args)Was für eine Sprache soll das denn sein? Das ist weder C, noch C++. Ich vermute ja mal, dass das dieses komische C++/CLI-Zeugs ist. Das ist von Microsoft als Interoperabilitätssprache zwischen C++ und dem ganzen NET-Zeugs gedacht. Es ist aber kein C++, sondern eine eigene Sprache. Der Rest deines Beitrags erweckt jedoch den Eindruck, dass du der Meinung bist, gerade C++ zu benutzen.

Gnafoo
2011-12-04, 13:14:24
Ja das ist C++/CLI. Eine Sprache von der ich btw. abraten würde, solange man nicht gerade einen Wrapper für eine C++-Bibliothek o. ä. schreiben will.

Das Problem ist, dass es so viele Mechanismen doppelt gibt: STL und .NET-Container, Zeiger/Referenzen und Handles, native Klassen und .NET-Klassen, Garbage Collection und delete, new und gcnew, C++-Strings und .NET-Strings usw. Ziemlich hässlich sieht das ganze dann auch noch aus. Außerdem muss man sich bereits mit beiden Welten auskennen, um abzuwägen, welchen Mechanismus man gerade braucht.

C++/CLI hat eine klare Nische, für die es gut ist, nämlich die Interoperabilität zwischen .NET und nativen Code. Für alles andere ist es ziemlich unglücklich. Bei einer einfachen Anwendung würde ich eher zu C# oder VB.NET raten. Selbst wenn man die Interoperabilität braucht, würde ich nur einen dünnen Wrapper mit C++/CLI schreiben und den Rest in C#.

aths
2011-12-04, 16:37:00
Ja, ich dachte anfangs das sei im Prinzip C++ welches nur halt in eine Managed-Exe übersetzt wird.

Dank dem Finden von etwas C#-Quellcode kann ich die benötigten Routinen jetzt in Delphi schreiben. (Letztlich benötige ich erst mal "nur" bestimmte IDs, um die Abfrage von versteckten Funktionen zu ermöglichen. Diese IDs scheinen in einer .lib-Datei versteckt zu sein, wo ich jedoch das System noch nicht herausbekommen habe. Leider ist das SDK unter NDA so dass ich die .lib-Datei nicht einfach mal irgendwo hochladen kann.)

Die C++/CLI-Nutzung liegt bei mir erst mal auf Eis. Es könnte aber sein dass ich irgendwann eine DLL schreiben muss, welche einen C-Header einbindet, dessen Funktionalität abstrahiert und nach außen zur Verfügung stellt. Lässt sich C++/CLI eine solche DLL im Prinzip erstellen?

Coda
2011-12-04, 16:39:56
Wieso muss es C++/CLI sein, wenn du Delphi benutzt? Hä?

Falls du native code für .NET wrappen willst, dann ist C++/CLI das richtige.

aths
2011-12-04, 18:19:09
Es muss nicht C++/CLI sein. Ich habe ein SDK für einen API-Zugriff als C-Headerfile, welches sich nicht nach Delphi portieren lässt da der Funktions-Zugriff mit Absicht verschlüsselt wurde. Im Notfall müsste ich dann eine DLL schreiben welche die API wrappt. Das müsste logischerweise in einer Programmiersprache erfolgen, in der man einfach C-Headerfiles einbinden kann.

ShadowXX
2011-12-04, 20:39:42
Es muss nicht C++/CLI sein. Ich habe ein SDK für einen API-Zugriff als C-Headerfile, welches sich nicht nach Delphi portieren lässt da der Funktions-Zugriff mit Absicht verschlüsselt wurde. Im Notfall müsste ich dann eine DLL schreiben welche die API wrappt. Das müsste logischerweise in einer Programmiersprache erfolgen, in der man einfach C-Headerfiles einbinden kann.
Dann nimm C oder C++ zum Schreiben der DLL.

Der Express-Compiler müsste doch eigentlich unter Projekte eine Vorlage/Template für DLLs anbieten.