dll question

Started by
7 comments, last by Sync Views 15 years, 10 months ago
I want to export a c++ class in a dll, I understand I can do this the same way as functions. However the problem is I don't want to export it exactly...lets take a window wrapper as an example

class __declspec(dllexport) Window
{
    public:
    static LRESULT CALLBACK MessageProc(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);//can I just hide this completly?
    
    HWND Hwnd; //<-- I do't want to require the user to include the windows headers, HWND is a pointer so I want with exported as void* Hwnd
    Window(unsigned Width, unsigned Height, const std::string &Caption);
    ~Window();
    void MessageLoop();//using PeekMessage so returns once there no messages
}

Advertisement
Use an abstract base class that contains only the interface you want to expose, inherit your Window class from that and export a factory function in your DLL that supplies instances of that class.
I'd recommend exporting an abstract class instead, and then provide an implementation in the DLL. For example:

Header shared between DLL and EXE:
class Window{public:   Window(unsigned Width, unsigned Height, const std::string &Caption) {}   virtual ~Window() {}   virtual void MessageLoop() = 0;};__declspec(dllexport) Window* CreateWindow(unsigned Width, unsigned Height, const std::string &Caption);__declspec(dllexport) void DestroyWindow(Window* pWindow);


Header private to the DLL:
#include "Window.h" // The name of the shared header class WindowImpl : public Window{public:   WindowImpl(unsigned Width, unsigned Height, const std::string &Caption);   virtual ~WindowImpl();   virtual void MessageLoop();};


Implementation in the DLL:
#include "Window_impl.h" // The name of the private header WindowImpl::WindowImpl(unsigned Width, unsigned Height, const std::string &Caption){   // Implemetation here}WindowImpl::~WindowImpl(){   // Implemetation here}void WindowImpl::MessageLoop(){   // Implemetation here}Window* CreateWindow(unsigned Width, unsigned Height, const std::string &Caption){   return new WindowImpl(Width, Height, Caption);}void DestroyWindow(Window* pWindow){   delete pWindow;}


That way the EXE just sees the abstract class and has no knowledge of the details. This also has the advantage that you don't need to export the class itself, just the two create and destroy functions.
So like this?
	class __declspec(dllexport) Core	{		public:		Core();		virtual void Release()=0;		bool WndClose;				virtual bool     WindowCreate(unsigned Width, unsigned Height, const std::string &Caption)=0;		virtual unsigned WindowLoop  (unsigned Speed, void(*Update)(Core*), void(*Render)(Core*))=0;		virtual void WindowDestroy()=0;	};	Core* CoreCreate();        //implement in this class	class LibCore : public Core	{		public:		bool Quit;		LibCore();		HWND Wnd;				virtual bool     WindowCreate(unsigned Width, unsigned Height, const std::string &Caption);		virtual unsigned WindowLoop  (unsigned Speed, void(*Update)(Core*), void(*Render)(Core*));		virtual void WindowDestroy();		virtual void Release();	};
Quote:Original post by Sync Views
So like this?
*** Source Snippet Removed ***
Not exactly. You don't use __declspec(dllexport) on the class, only on the Create function.
ok now I'm confused...if I don't export the class how can I use it in my app?
Quote:Original post by Sync Views
ok now I'm confused...if I don't export the class how can I use it in my app?


This is the beauty of virtual methods; they can "cross" the boundaries of EXEs and DLLs, do you don't need to declare them DLL exportable
Quote:Original post by Sync Views
ok now I'm confused...if I don't export the class how can I use it in my app?


Err - a header file?
Won't two diffrent compilers handle the class diffrently though (eg put something in a diffrent order in memory, or mayby one aligned it to 32bits and one didn't) so that passing the class to and from the dll no longer works? Or is that saying use virtual methods and don't allow direct access to any data?

This topic is closed to new replies.

Advertisement