Archived

This topic is now archived and is closed to further replies.

WickedImp

Problems with Win32 DLL and instances/handles

Recommended Posts

WickedImp    122
Antother day, another problem Last time I only forgot to set the right parameter to get it working. Now it seems a little more difficult: I try to create a window via CreateWindowEx (u would say: he? what''s your problem dude?) ... in a Win32 DLL. (u would say: so what?) ... Ok, some more descriptions about the problem: I got three files. The first is the EXE (i.e. demo.exe). The second is a DLL (i.e. engine.dll). This DLL is compiled into the EXE via headers and .lib file. Now to the last one. This DLL is a renderer (i.e. gpu_gl.dll). The first DLL searches for other dlls in a specific directory. Loads them (via LoadLibrary) and checks what this plugin is for (graphics (gpu_*), sound (spu_*), network (net_*)). After a little config screen. The gpu plugin, its resolution and if it should run fullscreen is selected. The engine now loads the plugin again (after search they were unloaded) and runs its init function. This init function (located in the gpu plugin). Should also handle the events and windows. So here we go: the class constructor of the plugin gets it own instance by calling GetModuleHandle( "gpu_gl.dll" ) and it receives (I thought) a valid handle. Then it registers it window class via RegisterClassEx (with this handle) without problems. Later I come t the point where I have to create the window. I use CreateWindowEx for this. Using the same handle will make the CreateWindowEx to fail. And GetLastError is set to 6 (The handle is invalid / ERROR_INVALID_HANDLE). I also tried to use the handles of GetModuleHandle(NULL) and GetModuleHandle("engine.dll")... they point to different addresses but they won''t wotk, too. Then I compared the instance given back by LoadLibrary with the instance of GetModuleHandle("gpu_gl.dll"). They are the same... My last problem was a problem with resources linked to the engine.dll. I tried to run DialogBox with the instance of the demo.exe and not with the instance of the engine.dll. DialogBox could not find the resources (but the handle itself was ok). And I think that DialogBox is calling CreateWindow somewhere with the given instance. Means: It works in the engine.dll, but not in the gpu_gl.dll... What happened? What is the magic behind the window and its instance. Are there limitations I did not find in the help files? The only difference between gpu and engine is the way they are loaded/linked to the demo.exe...

Share this post


Link to post
Share on other sites
Sneftel    1788
Hmm..... is CreateWindowEx being called from a DLL function, or an EXE function?


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
WickedImp    122
The DLLs all use classes. I think I call the CreateWindowEx from the dynamically loaded gpu_gl.dll. Hope this helps:

--- demo.exe ---

// returns the main class / from engine.dll
hEngine = engine::createEngine()
// returns the config class / from engine.dll
hConfig = hEngine->getConfig()
// show the config dialog via DialogBox / from engine.dll
hConfig->showConfig();

// get plugins / from engine.dll
hPlugins = hEngine->getPlugins()
// loads the gpu plugin / from engine.dll
hGPU = hPlugins->loadGPU( "gpu_gl.dll" );

// should create the window / from gpu_gl.dll
hGPU->init( , )

--- engine.dll ---

engine::gpu::MyGPU *engine:lugins::MyPlugin::loadGPU( lpFile ) {
LPFUNCCREATEGPU createGPU;
// load the dll
this->hInstance = LoadLibrary( lpFile );
// get entry point
createGPU = (LPFUNCCREATEGPU)GetProcAddress("createGPU");
// returns pointer to class
return createGPU();
}

--- gpu_gl.dll ---

MyGPU::MyGPU() {
this->hInstance = GetModuleHandle( "gpu_gl.dll" );
}

int MyGPU::init( tRes, nFullscreen ) {
// the window class
WNDCLASSEX wc = {
...
this->hInstance, // my module handle
...
}

// this does not fail
if( !RegisterClassEx( &wc ) ) return 0;

// using the class from above
// here it fails and GetLastError = 6
this->hWnd = CreateWindowEx(
...
this->hInstance,
...
);
}

Share this post


Link to post
Share on other sites
Sneftel    1788
Kay, I''m starting to get a feel for what you''re doing. Kind of convoluted, but I can''t see where anything would be going wrong related to address spaces. However, I don''t see the definition of createGPU there; perhaps you could post that. Also, MyGPU::init() isn''t a virtual function, is it?


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
WickedImp    122
First of all: Thx for replying to my question

The .def file of gpu_gl is exporting the createGPU. It is the only non class function in the dll. The engine_gpu.h file is included by engine.h which is the main header of the interface. Also used in demo.exe and engine.dll.

--- gpu_gl.dll ---

engine::gpu::MyGPU *createGPU( void ) {
engine::gpu::MyGPU *hGPU = NULL;

hGPU = new engine::gpu::MyGPU;
if( hGPU == NULL ) {
return NULL;
}

return hGPU;
}

--- engine_gpu.h ---

class MyGPU {
public:
MyGPU();
~MyGPU();
...
virtual engine::u16 init( engine::resolutiontRes, engine::u16 nFullScreen );

private:
resolution _tRes;
u16 _nFullScreen;
HINSTANCE _hInstance;
HWND _hWnd;
HDC _hDC;
HGLRC _hGLRC;
static LRESULT CALLBACK _wndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
};

Share this post


Link to post
Share on other sites
Galapaegos    277
WickedImp,

In msdn, lookup the GetLastError () or something like that, there is a link there that will print out the last error (if any) that was encountered in a copy/paste format. I''ve got the same thing working just fine (the exe loads the normal dll, and it loads the win32 windowing system). You should also double-check that your CreateWindowEx window actually gets created by trying it in just an exe with the params you are providing.

Let us know what happens,

-brad

Share this post


Link to post
Share on other sites
WickedImp    122
Thank u for the hint. I looked it up and found FormatMessage(...). I used as noticed in the helpfile. And it says the same as before GetLastError = 6 means "The handle is invalid. ERROR_INVALID_HANDLE".

Then I copied the init and the wndProc to the demo.exe source. I replaced this->_hInstance with a new handle. First I used the handle of NULL (demo.exe) : works. Then the one of "engine.dll" : works. Last but not least "gpu_gl.dll" : works also. What the hell is goin on there? Am I only allowed to run CreateWindowEx from the main handle (demo.exe)??? Why does RegisterClassEx not fail using those handles?????

I think it has something to do with LoadLibrary and the way the DLL is handled when loaded this way. I guess that the Init will work if it is linked into engine.dll...

Maybe someone can explain this...

Share this post


Link to post
Share on other sites