Home Page
  • March 13, 2025, 08:53:34 pm *
  • Welcome, Guest
Please login or register.

Login with username, password and session length
Advanced search  

News:

Official site launch very soon, hurrah!



Post reply

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.

Name:
Email:
Subject:
Message icon:

Bold Italicized Underline Strikethrough | Preformatted Text Left Align Centered Right Align
Insert Image Insert Hyperlink Insert Email Insert FTP Link | Glow Shadow Marquee | Superscript Subscript Teletype | Insert Table Insert Code Insert Quote | Insert Unordered List Insert Ordered List Horizontal Rule | Remove Formatting Toggle View
Smiley Wink Cheesy Grin Angry Sad Shocked Cool Huh Roll Eyes Tongue Embarrassed Lips sealed Undecided Kiss Cry
Verification:
Type the letters shown in the picture
Listen to the letters / Request another image

Type the letters shown in the picture:
Please stop spamming. Your spam posts are moderated and will never be displayed on the internet. What is eighty-eight minus eighty-six (spell out the answer):
Пожалуйста, прекратите спамить. Ваши спам-сообщения модерируются и никогда не будут отображаться в Интернете. What color is grass.:

shortcuts: hit alt+s to submit/post or alt+p to preview


Topic Summary

Posted by: Dakusan
« on: September 28, 2009, 05:32:26 am »

Original post for Virtual Functions in DLLs can be found at https://www.castledragmire.com/Posts/Virtual_Functions_in_DLLs.
Originally posted on: 06/18/09

Since I am now working on making sure all my applications work in both Windows and Linux, I have been having to work a lot more with GCC recently (which I am basically totally switching too). It’s a bit trying having to learn an entirely different toolset after having used the same formula for many many years.

Linux shared objects are a bit different than Window’s DLLs in that all symbols are naturally exported instead of just the ones you specify, among other different behaviors like how the libraries are loaded and unloaded during runtime. The solution to the visibility problem is more recent as far as GCC goes, and is to use the visibility attribute. Symbol visibility in a shared library is very important for both symbol collision and library load time reasons. This means, however, that every functions/symbol needs to be marked as either not visible (for Linux), or exportable (for Windows).


I ran into a rather nasty problem however that I couldn’t find any information on when making a class exportable in a DLL. Basically, I had the following:


A.dll creation
A.h

//Determine whether we are exporting or importing functions from this DLL
#undef DLLEXPORT
#ifdef A_DLL
   #define DLLEXPORT __declspec(dllexport)
#else
   #define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT class a
{
   public:
   int x;
   void a_foo();
   virtual void a_bar();
};
A.cpp

#define A_DLL
#include "A.h"
#include "stdio.h"
void a::a_foo() {printf("a_foo");}
void a::a_bar() {printf("a_bar");}
Compiling A.dll

g++ -c A.cpp -o A.o
g++ -shared -Wl,--output-def=libA.def -Wl,--out-implib=./libA.a -Wl,--dll A.o -o ./A.dll

B.dll creation
B.h

//Determine whether we are exporting or importing functions from this DLL
#undef DLLEXPORT
#ifdef B_DLL
   #define DLLEXPORT __declspec(dllexport)
#else
   #define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT class b
{
   public:
   int x;
   void b_foo();
   virtual void b_bar();
};
B.cpp

#define B_DLL
#include "B.h"
#include "stdio.h"
void b::b_foo() {printf("b_foo");}
void b::b_bar() {printf("b_bar");}
Compiling B.dll

g++ -c B.cpp -o B.o
g++ -shared -Wl,--output-def=libB.def -Wl,--out-implib=./libB.a -Wl,--dll B.o -o ./B.dll

main.exe creation
main.cpp

#include "A.h"
#include "B.h"

int main()
{
   a a_var;
   a_var.a_foo();
   a_var.a_bar();

   b b_var;
   b_var.b_foo();
   b_var.b_bar();
   return 1;
}
Compiling main.exe

g++ -c main.cpp -o main.o
g++ -c main.o -o ./main.exe -L./ -lA -lB

The problem that occurred was when only 1 of the DLL files was included on Windows, everything worked fine, but when both were included, I could only access the virtual functions from one of the 2. I was getting an error about “required class export or error due to vtable not being found”.

After many hours of tinkering and fruitless research, I stumbled upon the solution by accident. It turns out I was using the incorrect syntax. The classes should have been defined as “class DLLEXPORT x {}” instead of “DLLEXPORT class x {}”. Why it worked when only 1 of the DLLs was present, but clobbered with multiple DLLs, I have no idea.