DLL Usage

Started by
12 comments, last by ShawMishrak 22 years, 5 months ago
For a project I am working on, I have a set of home-made DLLs (renderers that export the same class, but use Direct3D, OpenGL, or whatever else depending on the DLL). Up to this point, I have just included whichever LIB file was appropriate to which rendering API I wanted to use. Now I am trying to just load the DLLs using LoadLibrary and GetProcAddress. I have a function in the DLLs that return a pointer to the renderer class. When I execute the code, the first call to a function of the renderer class works fine, after I grab the pointer using the function mentioned above, (creates rendering window and sets up either D3D or OGL), but all other function calls give Debug Assertion Errors. All the functions in the class are defined using "virtual" and there is no diference in how I define the first function and the other functions. Does anyone know what could be causing this? Thanks in advance.
Advertisement
Not sure but are u compiling the dlls and exe with the same C runtime library? (Try using Multithreaded dll /MD,/MDd)
I'm not exactly sure what you mean. the /MDd switch works with the compiler but doesn't solve the problem. I'm not sure what you mean by runtime library. I didn't know there were multiple ones. The error I am getting is: "The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention." I check what variables I pass to all the functions and they all match with the function definitions and the actual functions in the DLL.

Could it possibly be the fact that I have excluded all the member variables from the class definition in the EXE since I don't want to have to define two different classes for OGL and D3D (different variable names/types)?

Edited by - ShawMishrak on November 6, 2001 9:42:03 PM
The best way to do this is like the following:

In a "common" folder, you have a header declared like this:

  class IRenderer{public:    virtual void Initialize() = 0;    virtual void Draw( /* ... */ ) = 0;    // etc.};  


All the methods of IRenderer are pure virtual function, so you don''t need to declare the body of any of the methods.

Then, in your DLL, you have this:

  class COGLRender : public IRenderer{public:    void Initialize();    void Draw( /* ... */ );    // etc.};extern "C" IRenderer *GetRendererInterface();  


The COGLRenderer class implements all the methods of IRenderer (plus any internal ones it needs). The GetRendererInterface is just:

  IRenderer *GetRendererInterface(){    return new COGLRenderer();}  


Finally, in your exe, you use the following:

  IRenderer *pRenderer;void Initialize(){    HANDLE hLib = LoadLibrary( "ogl.dll" );    IRenderer *(*)() GetRendererInterface = GetProcAddress( hLib, "GetRendererInterface" );    pRenderer = GetRendererInterface();    pRenderer->Initialize();}  


I may have missed out a few things in that last part (notably error checking), but that''s the general idea. You''ve got to be careful of all the usual DLL things, like never allocate memory in the DLL and release it in the app (that includes the IRenderer interface pointer - have another exported function to free the interface, or include a Release() method in the interface which just does a "delete this")

Good luck!

codeka.com - Just click it.
That definitely provides some help. Thank you. Before I read your post I had it working to an extent, but the function order had to be the same or it would crash. i.e.:

class Renderer // in-EXE and DLL
{
Func 1();
Func 2();
};

would work but if I had Func2 first and Func1 last in the list in the EXE, it would cause problems if they weren''t in that order in the DLL. Does this still apply?
No, since these are virtual calls, the v-table is inherited from the IRenderer class, which is the same in both the DLL and the app. The compiler will be able to order them properly.

codeka.com - Just click it.
The only problem I''m having with your example at the moment is the line:
IRenderer *(*)() GetRendererInterface = GetProcAddress( hLib, "GetRendererInterface" );
I''ve substituted in the correct class names and such, but the compiler doesn''t like the "*(*)()" It spits out a syntax error: '')''.
The only problem I''m having with your example at the moment is the line:
IRenderer *(*)() GetRendererInterface = GetProcAddress( hLib, "GetRendererInterface" );
I''ve substituted in the correct class names and such, but the compiler doesn''t like the "*(*)()" It spits out a syntax error: '')''.
What is a class? and how do you do that in C?
quote:Original post by ShawMishrak
ones. The error I am getting is: "The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.".


This error is hinting that you may be using a different calling convention in your exe and dll.

I suspect the default calling convention for the exe and dll are different.

In exposing free functions outside of dll, it is always advisable to declare the calling convention as well.

Declare the calling convention in both the dll implementation and dll header for class member static and non member functions.

Check the win32 APIs header declaration, u will see that there is a WINAPI macro that defines the calling convention).

This topic is closed to new replies.

Advertisement