I'm building a DLL that links to OpenGL. But I get a problem when calling some functions such as glGenBuffers, because apparently __glewGenBuffers (and other glew buffer functions) are null. Everything compiles properly, and the same code works in the executable, but not in my DLL. I'm using VS 2010. Any ideas about linking to OpenGL from a DLL?
Edit: I forgot to mention, I'm actually trying to link an engine (static library) to the DLL, and the exe file uses it too (it does almost everything, except a small part that I want to put in my DLL). I would definitely be fine with using just OpenGL calls from the DLL though, instead of linking the engine, if I could get it to work better.
GLEW must do some tricks in order to deal with the context dependent function pointers on some plattforms. One of these plattforms is Windows. A foolproof way to make things working is to
Test if there's actually a OpenGL context bound
call glewInit()
everytime a function in the DLL is called that uses extended OpenGL functionality. I.e.
… some_DLL_exported_function(…)
{
if( NULL == wglGetCurrentContext() ||
GLEW_OK == glewInit() ) {
return …;
}
}
Related
I grepped inside GLEW while trying to solve my other question, concerning missing __glewX* symbols for Mac, and found that they are guarded by GLEW_APPLE_GLX.
When I attempt to build GLEW from source with that flag defined, I get undefined symbols (stuff like _glXGetClientString). Linking against X11 (-lX11) doesn't help.
Question: assuming defining GLEW_APPLE_GLX does indeed make sense, how can I fix the build?
When building an application that uses the X Server (XQuartz) instead of using CGL, you also need to add -lGL.
Ordinarily when building GL software on OS X you use OpenGL.framework (-framework OpenGL) and that gets you OpenGL and CGL/AGL functions but leaves out GLX.
You should also ditch any includes to things like <OpenGL/gl.h> and use <GL/gl.h> instead, as that will point to /usr/X11R6/include/GL/... instead of the OpenGL framework headers.
I want to fully use OpenGL 3.3 in my program, but glGenVertexArrays segfaults without some special initialization. I've looked at the GLEW source but couldn't find what is done for it to work.
I tried binding to GLEW, but OPTLINK either says the library is invalid (when compiled with VS2012) or the symbol is not found (uint glewInit() in a MinGW dll converted to lib with implib).
If there are only a few lines needed doing what GLEW does (I suppose I don't need 1000 lines of function getting) I would like to do that myself, when it's too much I would appreciate some help on building a lib that D actually accepts.
This is a good start : http://www.opengl.org/wiki/Load_OpenGL_Functions
Follow the links to The OpenGL Registry : http://www.opengl.org/registry/
Here you can find useful header files for your platform. I would recommend using GLEW or similar libs though.
If I do a LoadLibrary("msvcrt.dll") do I need to initialize the CRT somehow? Section 2 in the following document seems to say that I do, but I just get an undefined symbol error for _CRT_INIT when I try to call _CRT_INIT:
http://support.microsoft.com/kb/94248
Edit: I should have said that this is for a program that dynamically loads all the dlls that it uses, hence the call to LoadLibrary("msvcrt.dll").
Call DllMain() in it. If it relies on the C runtime, it will call CRT_INIT.
But a far better question is if a program is using something in msvcrt, there's no need to explicitly load the dll and initialize it, so why are you doing this?
If you're working in C++, have you declared _CRT_INIT as extern "C"?
Have you tried using the DUMPBIN utility ( http://support.microsoft.com/kb/177429 -- if you haven't your PATH up yourself, you'll have to use the Visual Studio Command Prompt I think) with the /EXPORTS switch to see which functions are available from the CRT DLL, just to double check?
If you get stuck, VS2005 and earlier (and presumably later...) come supplied with the source code for the runtime library. For VS2005, this is in VC/crt/src, relative to the VS install folder. It looks like _CRT_INIT is the right name -- see crtdll.c and dllcrt0.c, and it's a C function.
You must not call _CRT_INIT() but call CRT_INIT() (if you really must)
The link you referenced refers to using CRT_INIT() only when "Using the CRT Libraries When Building a DLL", and even then it is only one of two alternatives; the first probably being preferable in most cases.
I am converting my project to use DLLs and am trying to break apart my Singleton class to avoid using templates.
My class, LudoMemory, originally inherited from Singleton. I am trying to give it the functions to destroy and create itself now and have my main engine not rely on the Singleton.
I have written a simple destroy method like such:
LudoMemory *memory_Singleton = NULL;
void LudoMemory::Destroy()
{
LUDO_SAFE_DELETE(m_Singleton)
}
and upon running the program (no compiler errors) I recieve this error:
The procedure entry point
?Destroy#LudoMemory##SAXXZ could not
be located in the dynamic link library
LudoCore.dll
LudoCore is the project that LudoMemory belongs to. Why is this happening? How can I solve it?
you don't have multiple versions of ludocore.dll on your system, do you?
Procedure entry points errors usually mean: you compiled your project against ludocore.lib version x, and when running the program, it uses ludocore.dll version y, and version y does not define LudoMemory::Destroy().
Jacob's answer about multiple DLL versions seems likely.
Also, with some build systems, you must explicitly list which functions will be exported in a DLL.
Research your build environment, and see if you must provide a list of methods to be exported as an entry-point.
In Visual Studio build environment, also you could try by disabling the References in Linker Optimization Settings [ No(/OPT:NOREF)]
I was about to rebuild my library in Dev-C++, under Windows; however, the shader functionality I've added in the meantime is not supported, the compiler could not find the related functions (::glCreateShader(), ::glCreateProgram(), etc.)
Digging around the internet and the Dev-C++ folder, I've found that the OpenGL implementation (gl.h) is only v1.1. I've found recommendations to download the latest headers from SGI. I have found gl3.h, however, after closer scrutiny I have realized that gl.h is not included in my project anyway, and I should be looking at SDL/SDL_opengl.h.
EDIT: SDL_opengl.h does include gl.h and declares prototypes of the functions in question. So the question is, why ame I given compile-time errors rather than linker errors?
(My library only links against mingw32, libOpenGL32, libSDL, libSDL_Image and libSDL_Mixer, much like under OSX (except for mingw32, of course) where I didn't have any problem.)
How can I use OpenGL v2.0 shaders with Dev-C++ and SDL?
gl.h is only for OpenGL 1.1 (and in some cases up to 1.3 depending on which version of the file you are using and which operating system). For everything else you additionally need glext.h and probably glxext.h (Linux/Unix) or wglext.h (Windows).
All functions from newer versions of OpenGL must be linked at runtime. So in order to use them you must get the right function address and assign it to a function pointer. The easiest way to do this is by using something like GLEW.
The manual way would be something like this:
PFNGLCREATESHADERPROC glCreateShader = NULL;
glCreateShader = (PFNGLCREATESHADERPROC) wglGetProcAddress("glCreateShader");
or for Linux:
PFNGLCREATESHADERPROC glCreateShader = NULL;
glCreateShader = (PFNGLCREATESHADERPROC) glXGetProcAddress((GLubyte*) "glCreateShader");
If you define GL_GLEXT_PROTOTYPES before including glext.h you can omit the first line.
EDIT: SDL_opengl.h looks like it contains a copy of glext.h (not up to date though). So if you use that the above should still be valid. If you want to use a seperate glext.h you must define NO_SDL_GLEXT before including SDL_opengl.h. Also, the function prototypes aren't available as long as GL_GLEXT_PROTOTYPES isn't defined or you write them yourself.
EDIT2: Apparently SDL has its own GetProcAddress function called SDL_GL_GetProcAddress.
Can you load the addresses of the functions at runtime?
typedef GLhandle (APIENTRYP PFNGLCREATESHADERPROC) (GLenum shaderType);
PFNGLCREATESHADERPROC glCreateShader = NULL;
glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
typedef GLhandle (APIENTRYP PFNGLCREATEPROGRAMPROC) ();
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");