I've been having problems recently whilst trying to compile and load C files into gambit-c dynamically. Originally I was using gsc & gcc at the command prompt to statically link all of my files, but this got cumbersome as the number of c files grew. I have a file called "_Vector.ss" which binds to the C files "Vector.h" and "Vector.c", which works fine whilst using (compile-file "_Vector.ss") and then (load "_Vector"). The problems came when I tried to do this with a file "_W32Window.ss" which binds to the C files "W32Window.h" and "W32Window.c", which requires support from external libraries. The error I get is this (a few linker errors): C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x6db): undefined reference to `SwapBuffers@4' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x746): undefined reference to `ChoosePixelFormat@8' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x775): undefined reference to `SetPixelFormat@12' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x794): undefined reference to `wglCreateContext@4' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x7bd): undefined reference to `wglMakeCurrent@8' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x7f4): undefined reference to `wglMakeCurrent@8' C:\DOCUME~1\malune\LOCALS~1\Temp/ccMXbaaa.o:_W32Window.c:(.text+0x80b): undefined reference to `wglDeleteContext@4' collect2: ld returned 1 exit status I've tried modifying gsc-cc-o.bat so that the libs included were the same as the gcc that worked under the command line: "-mno-cygwin -lmingw32 -lgdi32 -lopengl32 -lglu32 -lgambc". But this did not change the outcome of the problem. So basically I can link things statically without any problems because I'm calling gcc manually, but when I start to dynamically link things go wrong. Am I missing something obvious? Any thoughts would be highly appreciated. Thanks, Edward Tate PS: Here are the files: _W32Window.ss: (c-declare "#include \"W32Window.h\"") (c-declare "#include \"W32Window.c\"") (c-define-type SW32Window (struct "SW32Window")) (c-define-type SW32Window* (pointer SW32Window)) (define wnd-create! (c-lambda () void "wndCreate")) (define wnd-destroy! (c-lambda () void "wndDestroy")) (define wnd-create-instance! (c-lambda (char-string) int "wndCreateInstance")) (define wnd-set! (c-lambda (int int int int) void "wndSet")) (define wnd-handle-message (c-lambda () int "wndHandleMessage")) ;(define wnd-swap-buffers ; (c-lambda () void "wndSwapBuffers")) (define vk-up (c-lambda () int "vkUp")) (define vk-down (c-lambda () int "vkDown")) (define vk-left (c-lambda () int "vkLeft")) (define vk-right (c-lambda () int "vkRight")) (define vk-escape (c-lambda () int "vkEscape")) W32Window.h: //--------------------------------------------------------------------------- // Lib Name: Win32 Window // Author: Deweta //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // W32Window Header //--------------------------------------------------------------------------- #include <windows.h> #define WIN32_LEAN_AND_MEAN #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> //--------------------------------------------------------------------------- // W32Window Definitions //--------------------------------------------------------------------------- enum { RENDERER_W32 = 0, RENDERER_GL = 1, RENDERER_D3D = 2 }; struct SGLContext { GLuint _pixelFormat; HGLRC _hRC; }; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; //struct SD3DContext //{ // D3DPRESENT_PARAMETERS _D3DPP; // LPDIRECT3D9 _pD3D; // LPDIRECT3DDEVICE9 _pD3DDevice; //}; struct SW32Window { // Used for GL/D3D window void *_renderContext; // Device DEVMODE _dmScreenSettings; HDC _hDC; // Window HFONT _defaultFont; DWORD _dwStyle; DWORD _dwExStyle; WNDCLASS _wc; RECT _rect; HWND _hWnd; HINSTANCE _hInstance; // Window Flags int _isActive; int _isFullscreen; // Event MSG _eventMsg; // Keyboard int _keys[256]; }; struct SW32Window *this; //--------------------------------------------------------------------------- // W32Window Inline Functions //--------------------------------------------------------------------------- // W32 wndProc LRESULT CALLBACK wndProc0(struct SW32Window *this, HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK wndProc1(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); // Keyboard int vkUp(void); int vkDown(void); int vkLeft(void); int vkRight(void); int vkEscape(void); //--------------------------------------------------------------------------- // W32Window Prototypes //--------------------------------------------------------------------------- // Constructor void wndCreate(void); // Destructor void wndDestroy(void); // Event int wndHandleMessage(void); // int wndCreateInstance(const char *title); int wndDestroyInstance(void); void wndSet(int w, int h, int bpp, int fs); // void wndSwapBuffers(void); // GL Context int wndGLCreate(const char *title); int wndGLDestroy(void); int wndGLCreateContext(void); int wndGLDestroyContext(void); W32Window.c: int vkUp(void) { return this->_keys[VK_UP]; } int vkDown(void) { return this->_keys[VK_DOWN]; } int vkLeft(void) { return this->_keys[VK_LEFT]; } int vkRight(void) { return this->_keys[VK_RIGHT]; } int vkEscape(void) { return this->_keys[VK_ESCAPE]; } // Constructor void wndCreate(void) { this = malloc(sizeof(struct SW32Window)); this->_renderContext = NULL; } // Destructor void wndDestroy(void) { if(this->_renderContext) free(this->_renderContext); free(this); } // Event int wndHandleMessage(void) { if(PeekMessage(&this->_eventMsg, NULL, 0, 0, PM_REMOVE)) { if(this->_eventMsg.message == WM_QUIT) { return 0; } else { TranslateMessage(&this->_eventMsg); DispatchMessage(&this->_eventMsg); return 1; } } return 1; } // int wndCreateInstance(const char *title) { if(!RegisterClass(&this->_wc)) { MessageBox(NULL, "Failed to register window class", "Error", MB_OK | MB_ICONEXCLAMATION); return -1; } if(this->_isFullscreen) { if(ChangeDisplaySettings(&this->_dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { MessageBox(NULL, "Fullscreen not supported by your\n video card.", "Error", MB_OK | MB_ICONSTOP); return -1; } ShowCursor(FALSE); } AdjustWindowRectEx(&this->_rect, this->_dwStyle, FALSE, this->_dwExStyle); if(!(this->_hWnd = CreateWindowEx(this->_dwExStyle, "W32Window", title, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | this->_dwStyle, 0, 0, this->_rect.right - this->_rect.left, this->_rect.bottom - this->_rect.top, NULL, NULL, this->_hInstance, NULL))) { MessageBox(NULL, "Window creation error.", "Error", MB_OK | MB_ICONEXCLAMATION); return -1; } if(!(this->_hDC = GetDC(this->_hWnd))) { MessageBox(NULL, "Can't create a device context.", "Error", MB_OK | MB_ICONEXCLAMATION); return -1; } ShowWindow(this->_hWnd, SW_SHOW); SetForegroundWindow(this->_hWnd); SetFocus(this->_hWnd); return 0; } int wndDestroyInstance(void) { if(this->_isFullscreen) { ChangeDisplaySettings(NULL, 0); ShowCursor(TRUE); } if(this->_hDC && !ReleaseDC(this->_hWnd, this->_hDC)) { return -1; } if(this->_hWnd && !DestroyWindow(this->_hWnd)) { return -1; } if(!UnregisterClass("W32Window", this->_hInstance)) { return -1; } return 0; } // Set the parameters of a window void wndSet(int w, int h, int bpp, int fs) { // this->_rect.left = (long) 0; this->_rect.right = (long) w; this->_rect.top = (long) 0; this->_rect.bottom = (long) h; // this->_hInstance = GetModuleHandle(NULL); // this->_wc.hInstance = this->_hInstance; this->_wc.lpfnWndProc = (WNDPROC) wndProc1; this->_wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); this->_wc.hCursor = LoadCursor(NULL, IDC_ARROW); this->_wc.hbrBackground = NULL; this->_wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; this->_wc.lpszClassName = "W32Window"; this->_wc.lpszMenuName = NULL; this->_wc.cbClsExtra = 0; this->_wc.cbWndExtra = 0; // this->_isFullscreen = fs; if(fs == 1) { this->_dwExStyle = WS_EX_APPWINDOW; this->_dwStyle = WS_POPUP; memset(&this->_dmScreenSettings, 0, sizeof(this->_dmScreenSettings)); this->_dmScreenSettings.dmSize = sizeof(this->_dmScreenSettings); this->_dmScreenSettings.dmPelsWidth = w; this->_dmScreenSettings.dmPelsHeight = h; this->_dmScreenSettings.dmBitsPerPel = bpp; this->_dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH; } else { this->_dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; this->_dwStyle = WS_OVERLAPPEDWINDOW; } } LRESULT CALLBACK wndProc0(struct SW32Window *this, HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { case WM_CLOSE: PostQuitMessage(0); return 0; case WM_KEYDOWN: this->_keys[wParam] = 1; return 0; case WM_KEYUP: this->_keys[wParam] = 0; return 0; case WM_SIZE: return 0; default: return DefWindowProc(hWnd, iMsg, wParam, lParam); } return 0; } // LRESULT CALLBACK wndProc1(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { return wndProc0(this, hWnd, iMsg, wParam, lParam); } // Double buffering void wndSwapBuffers(void) { SwapBuffers(this->_hDC); } // GLContext int wndGLCreate(const char *title) { if(wndCreateInstance(title) < 0) return -1; if(wndGLCreateContext() < 0) return -1; return 0; } int wndGLDestroy(void) { if(wndDestroyInstance() < 0) return -1; if(wndGLDestroyContext() < 0) return -1; return 0; } int wndGLCreateContext(void) { struct SGLContext *rc = (struct SGLContext*) this->_renderContext; if(!(rc->_pixelFormat=ChoosePixelFormat(this->_hDC, &pfd))) return -1; if(!SetPixelFormat(this->_hDC, rc->_pixelFormat, &pfd)) return -1; if(!(rc->_hRC=wglCreateContext(this->_hDC))) return -1; if(!(wglMakeCurrent(this->_hDC, rc->_hRC))) return -1; return 0; } int wndGLDestroyContext(void) { struct SGLContext *rc = (struct SGLContext*) this->_renderContext; if(rc->_hRC) { if(!wglMakeCurrent(NULL, NULL)) return -1; if(!wglDeleteContext(rc->_hRC)) return -1; rc->_hRC = NULL; } return 0; }