Undefined reference to GetStockObject@4
-
Hi all,
also, ich hab mir da ein kleines Progrämmchen geschrieben:#define STRICT #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); const char szAppName[]="Ein eigenes Fenster"; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { HWND hWnd; MSG msg; WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszClassName = szAppName; wc.lpszMenuName = NULL; RegisterClass(&wc); hWnd = CreateWindow( "Titelleiste", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch(message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }
Beim Compilieren mit
c++ (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
kommt immer die Meldung:
/cygdrive/d/DOKUME~1/Markus/LOKALE~1/Temp/ccv4VqdF.o:win2.c:(.text+0x67): undefined reference to `_GetStockObject@4' collect2: ld returned 1 exit status
Toll, und was kann ich dagegen tun?
-
Du musst noch die "Gdi32.lib" in Deinen Linker-Settings aufnehmen, damit diese auch beim Linken verwendet wird...
-
Ich hab mal ein bischen rumgespielt. Wenn ich ihn nur compilen und assembeln lasse, und die entstandene Datei mit alink zu linken versuche, findet er alle WinAPI-Funktionen nicht. Das gleiche mit nachträglichem ld. Und nebenbei: im gesammten cygwin-Verzeichnis gibt es keine Datei namens gdi32.lib. Aber ich habe eine Lösung. In Assembler sieht die so aus:
LoadLibrary: IMPORT LoadLibraryA kernel32.dll GetProcAddress: IMPORT GetProcAddress kernel32.dll proc GSO use32 jmp over LibName db "GDI32.DLL",0 FktName db "GetStockObject",0 over: push offset LibName call [LoadLibrary] push offset FktName push eax call [GetProcAddress] jmp eax
Problem: Wie sag ich sowas C? Es wäre in etwa das gleiche wie:
HGDIOBJ GSO(int obj) { FARPROC addr = GetModuleHandle(LoadLibrary("GDI32.DLL"),"GetStockObject"); return addr(obj); }
Mal testen... Nö, da gibt es "too many arguments to function" und eine "invalid conversation 'int' to 'void*'" auf der "return"-Zeile von GSO. Hä??
Tschö,
nullplan
P.S.: Wie kann ich eigentlich dem Compiler sagen, dass ich die-und-die Funktion statisch laden würde? Unter Pascal (ich kenn es halt besser) sage ich einfachfunction bla(blubb:arguments); external 'blubber.dll';
Was ist das in C?
-
Ich find das süß
was ein mensch mit einer Funktion alles falsch machen kann
und das nur weil ihm niemand gesagt hat, das es sowas wie es die MSDN Library gibt
naja.. hier mal nen sample wie de schön aus ner dll ne func. laden kannst
typedef int (__stdcall*gso)(int); gso GetSO = NULL; HGDIOBJ GetSObject(int iObject) { ::HINSTANCE__* hDll = ::LoadLibrary("gdi32.dll"); if (hDll == NULL) return -1; GetSO = reinterpret_cast<gso>(::GetProcAddress (hDll, "GetStockObject")); if (GetSO == NULL) { ::FreeLibrary(hDll); return -1; } HGDIOBJ objTmp = ::GetSO(iObject); ::FreeLibrary(hDll); return objTmp; }
-
Soll ich jetzt lachen? Wo, glaubst du, hab ich die Info her, dass GetStockObject den obskuren Datentyp HGDIOBJ zurückgibt? Und dass mit FARPROC hab ich mir auch aus den Rippen gesäbelt, ja? Nebenbei, stehen Sachen wir der statische DLL-Import bei C etwa im MSDN drin? Wenn ja, wo? Ich benutzte es bis jetzt immer nur als das, als was es gedacht war: Referenz zu Windows-Funktionen.
Aber zu der Quelle: Die ganzen :: bedeuten, dass du C++ nimmst, oder? Sind das Aufrufe? Checkt der Compiler nicht, dass man was aufruft, ohne diese ::? Und was ist ein reinterpret_cast? Ich kenne nur typecast. und da schreibt man es nicht davor. Und was ist das für eine typedef am Anfang. Sorry, ich bin bei C++ noch Newbie. Und so ein typedef ist mir bis jetzt noch nicht über den Weg gelaufen. Nebenbei: Ich hatte mir gerade eine so schöne DLL gebastelt, die den ASM-Code ausführen kann. Ich wollte die eigentlich statisch Linken. Wie? Ich müsste dem Compiler vermutlich sagen, dass die Funktion GSO extern ist und dem Linker ein "cdll.dll" zukommen lassen. Aber egal, ich probier mal deinen Code aus...
Musste zwar erst einige Typen casten (die Zeilen "return -1;" in "return (void*)(-1);" und die finale Zuweisung in "HGDIOBJ objTmp = (void*)(::GetSO(obj));", aber jetzt klappts: Ein weißes Fenster ohne Menü wird angezeigt und immer wieder wiederhergestellt. Es könnte gar nicht besser werden.
Danke und Tschö,
nullplan