C++ Dll to C++
Hi all.
I'm trying to rewrite an engine of mine and I tough I'd put it into a DLL. This is because later on I'd like to have it working in C# as well.
I know how to export a normal function like "int RandomNumber() { return rand();}" or a variable but those won't help me.
I'd like to have classes exported. Untill now I've understood how this thing works
"#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif" but from what I read on the internet only the same version of visualC++ can compile that and that's a big nono for me.
I'm not worried about the classes themselves as I'd like to introduce a procedural style of work first. (Functions like PositionEntity(CEntity ent,CVec3 vec); ).
But how would I export a function like that. It needs to know what a CEntity is and what a CVec3 is and thus I'd have to export the classes right?
If someone could help me I'd be very thankfull.
Quote:Original post by LorinAtzbergerThat's a fact of life with C++ - there is no standard for how the binary should look AFAIK, so a C++ DLL built with one compiler won't necessarily work with another compiler.
from what I read on the internet only the same version of visualC++ can compile that and that's a big nono for me.
You've got to define a procedural interface with plain C functions for that to work.
Quote:I'm not worried about the classes themselves as I'd like to introduce a procedural style of work first. (Functions like PositionEntity(CEntity ent,CVec3 vec); ).Instead of passing by value (e.g. func( CEntity ) ), pass by pointer (e.g. func( CEntity* ) ), and then all the compiler needs to know is that such a class exists - it doesn't need to know anything about it.
But how would I export a function like that. It needs to know what a CEntity is and what a CVec3 is and thus I'd have to export the classes right?
I was anyway going to place pointers there but I forgot to write them here.
So how do I tell the compiler that such a class exists?
Here is my code for the engine.
If I can get this up running from the DLL then I can figure out the rest.
Thank you! You are very helpfull
So how do I tell the compiler that such a class exists?
Here is my code for the engine.
If I can get this up running from the DLL then I can figure out the rest.
class CEngine{private: bool m_FullScreen; // Set full screen as default HWND m_HWnd; // This is the handle for the window RECT m_Rect; // This holds the window dimensions HDC m_HDC; // General HDC - (handle to device context) HGLRC m_HGLRC; // General OpenGL_DC - Our Rendering Context for OpenGL int m_Depth;public: CEngine(HWND hWnd) { m_HWnd = hWnd; GetClientRect(hWnd,&m_Rect); m_HDC = GetDC(hWnd); m_Depth = 32; SetupPixelFormat(m_HDC); m_HGLRC = wglCreateContext(m_HDC); wglMakeCurrent(m_HDC,m_HGLRC); SizeOpenGLScreen(m_Rect.left -m_Rect.right,m_Rect.top -m_Rect.bottom); }private: bool SetupPixelFormat(HDC dc) { PIXELFORMATDESCRIPTOR pfd = {0}; int pixelformat; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the structure pfd.nVersion = 1; // Always set this to 1 // Pass in the appropriate OpenGL flags pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwLayerMask = PFD_MAIN_PLANE; // We want the standard mask (this is ignored anyway) pfd.iPixelType = PFD_TYPE_RGBA; // We want RGB and Alpha pixel type pfd.cColorBits = m_Depth; // Here we use our #define for the color bits pfd.cDepthBits = m_Depth; // Depthbits is ignored for RGBA, but we do it anyway pfd.cAccumBits = 0; // No special bitplanes needed pfd.cStencilBits = 0; // We desire no stencil bits if ( (pixelformat = ChoosePixelFormat(m_HDC, &pfd)) == FALSE ) { MessageBox(NULL, L"ChoosePixelFormat failed", L"Error", MB_OK); return FALSE; } // This sets the pixel format that we extracted from above if (SetPixelFormat(m_HDC, pixelformat, &pfd) == FALSE) { MessageBox(NULL, L"SetPixelFormat failed", L"Error", MB_OK); return FALSE; } return TRUE; } void SizeOpenGLScreen(int width,int height) { if(height==0) height=1; glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(float)width/(float)height,1,150.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void ClearDevice() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer }public: void Render() { ClearDevice(); SwapBuffers(m_HDC); }};typedef CEngine * TEngine;TEngine CreateEngine(HWND hWnd){ return new CEngine(hWnd);}void Render(){}void Render(TEngine eng){ eng->Render();}
Thank you! You are very helpfull
Quote:Original post by LorinAtzberger
I was anyway going to place pointers there but I forgot to write them here.
So how do I tell the compiler that such a class exists?
I'm sorry, I don't really have time to read the code but I can answer this question for you.
What you want is something called "Forward declaration"
Basically before you declare a pointer variable in your code you just write:
class CEntity;
That just tells to the compiler that such a class exists somewhere and at some point it will get defined. That is enough for the compiler to understand declarations of form:
CEntity *pEnt;
All pointers are essentially the same, the compiler just needs to know that CEntity is some kind of class.
Quote:Original post by LorinAtzberger
But from what I read on the internet only the same version of visualC++ can compile that and that's a big nono for me.
Why is it a nogo for you? Do you plan to release binaries only for others to use? Well... simply offer binaries for the most common compilers.
If that's not the case why do you care?
To export a class:
class DLLTEST_API foo{};
I'll ask again. Why is it a nogo for you? If you're the only one working on your engine then just stick with a c++ approach and forget the COM approach (for gods sake, don't overcomplicate things if it's not even necessary).
When you create a DLL that's to be consumed from multiple languages, you need to use an agreed binary interface - the most common ones are the C ABI, COM+ and the Microsoft CLR (.NET).
This approach is pretty useless. You don't need to release seperate DLLs for each compiler, you need to release seperate DLLs for each compiler option that affects either the binary interface; for Visual Studio you need [Release|Debug]*[Static CRT|Dynamic CRT]*[Checked STL | Unchecked STL] - that's 8 versions just for the commonly altered options.
And then you still can't use it from C# without either creating either a C or C++/CLI wrapper.
Quote:Original post by SiS-Shadowman
Why is it a nogo for you? Do you plan to release binaries only for others to use? Well... simply offer binaries for the most common compilers.
This approach is pretty useless. You don't need to release seperate DLLs for each compiler, you need to release seperate DLLs for each compiler option that affects either the binary interface; for Visual Studio you need [Release|Debug]*[Static CRT|Dynamic CRT]*[Checked STL | Unchecked STL] - that's 8 versions just for the commonly altered options.
And then you still can't use it from C# without either creating either a C or C++/CLI wrapper.
Please note that passing an object as a pointer doesn't solve anything.
You're passing from one binary to another, a pointer to a piece of memory that represents an object.
If the compilers doesn't agree on that exact memory layout to be an object, there will be a problem (member alignment, order optimizations, v-table location etc).
You're passing from one binary to another, a pointer to a piece of memory that represents an object.
If the compilers doesn't agree on that exact memory layout to be an object, there will be a problem (member alignment, order optimizations, v-table location etc).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement