Wrapper main schreiben -> undefined reference to WinMain (Bug?) [Code::Blocks]
-
Hallo zusammen,
Für ein Projekt hatte ich viel mit Konsolenargumente zu tun, deswegen hatte ich mir eine Wrapper-main() geschrieben, die anstatt argc/argv einen std::vectorstd::string übergibt, um das einfacher bearbeiten zu können.
Nun habe ich das ganze auch mit der WinMain() gemacht und bin auf etwas seltsames gestoßen, was sich reproduzieren lässt, ich konnte das auf folgendes beschränken:
Hauptprogramm, main.cpp:#include <my_main.hpp> void my_main() { }
Lib, my_main.hpp:
#include <windows.h> #include <vector> #include <string> struct main_args { static std::vector<std::string> console_args; static HINSTANCE handle_instance; static int command_show; }; void my_main();
Lib, my_main.cpp:
// Definition der statics int APIENTRY WinMain(HINSTANCE handle_instance, HINSTANCE, LPSTR, int command_show) { int arg_count; LPWSTR *arg_vector = CommandLineToArgvW(GetCommandLineW(), &arg_count); auto &console_args = main_args::console_args; console_args.reserve(arg_count); for (size_t i = 0; i < static_cast<size_t> (arg_count); ++i) { wstring current = arg_vector[i]; console_args.push_back(string(current.begin(), current.end())); } main_args::handle_instance = handle_instance; main_args::command_show = command_show; my_main(); return 0; }
Nun bekomme ich jedoch eine undefined reference to WinMain.
Durch ausprobieren habe ich herausgefunden, dass der Linker Error nicht mehr auftritt, sobald ich die Argumente der WinMain() nutze, z.B.:if (main_args::console_args.size() > 1);
oder
main_args::command_show = main_args::command_show + 0;
Meine Frage ist nun: Ist das ein Bug, oder habe ich irgendetwas übersehen?
Ich nutze Code::Blocks.
lg
Nathan
-
Da du "Lib" schreibst vermute ich eine statische Bibliothek und dieses Verhalten kenne ich vom MSVC. Der Inhalt eines Moduls einer statischen Bibliothek wird offenbar nur zum Linken herangezogen, wenn der Compiler Referenzen aus dem Hauptprogramm feststellen kann.
Auch werden keine globalen Objekte aus solchen Libs initialisiert solange kein Zugriff von außen darauf erfolgt ... leider!Ich hatte übrigens genau das gleiche Problem wie du und habe es letztlich so gelöst, dass ich den gesamten Wrapper in eine "main.hpp" verlagert habe, eine "main.cpp" gibt es da nicht.
Da ja ein EXE-Projekt in der Regel nur in einer einzigen CPP sein "main" implementiert, muss eben sichergestellt sein, dass eine solche "main.hpp" eben nur dort inkludiert wird und sonst nirgends.Eventuell kann man mit bestimmten pragmas das Verhalten abändern, aber dann werden vielleicht andere Compiler wieder nicht damit umgehen können.
PS: Wenn es aber einen Standard-Weg gibt den gesamten Inhalt von statischen Libs mitzulinken, würde mich dieser sehr interessieren
-
Ach, du meinst, eine main.hpp die wie eine Source-File ist (abseits der ODR)?
Ich probiere es mal aus.Edit: Jupp, klappt. Habe zum Testen mal das source-File inkludiert (ja, ja, ich weiß
). Aber für eine Alternative bin ich dennoch offen. Solange nutze ich meine avoid_lnk_err()-Funktion.