Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


TheComet

Member Since 02 Oct 2013
Offline Last Active Today, 06:20 AM

Topics I've Started

dllimport/dllexport with multiple depending shared libs

18 February 2015 - 06:45 AM

Most people will tell you that every DLL will have to #include an export.h header file with something like the following in it:

#ifdef LIBRARY_BUILDING
#   define LIBRARY_API __declspec(dllexport)
#else
#   define LIBRARY_API __declspec(dllimport)
#endif
 
Then, when you build the library, simply globally define LIBRARY_BUILDING, and when you're linking against the library, don't define it.
 
My questions are: 
1) What happens when you have multiple DLLs that depend on each other and include each other's header files? Do I need to create two export.h header files, one for each DLL?
2) If one global export.h file is sufficient for all DLLs, can you please explain to me in the example below why the linker doesn't throw any errors or warnings?
 
Here's an example demonstrating what I mean:
 
foo.DLL

#ifdef FOO_BUILDING
#   define FOO_API __declspec(dllexport)
#else
#   define FOO_API __declspec(dllimport)
#endif


FOO_API some_function_foo(void);
 
bar.DLL

#ifdef BAR_BUILDING
#   define BAR_API __declspec(dllexport)
#else
#   define BAR_API __declspec(dllimport)
#endif


#include "foo.h"


/* this function calls some_function_foo() from foo.DLL */
BAR_API some_function_bar(void);
 
application

#include "bar.h"


int main()
{
    some_function_bar();
    return 0;
}
 
When this project gets built, the following occurs:
1) foo.DLL: FOO_BUILDING gets defined, which means all of foo's functions are declared with dllexport.
2) bar.DLL: BAR_BUILDING gets defined, but FOO_BUILDING isn't defined. This means all of foo's functions are declared with dllimport, and all of bar's functions are declared with dllexport when bar includes foo's headers. I would assume this is the intended behaviour.
3) application: Neither FOO_BUILDING nor BAR_BUILDING is defined, therefore all of foo's and bar's functions are declared with dllimport.
 
If I had only one export.h header file, then step 2) would not be possible, because either everything gets declared with dllexport or everything gets declared with dllimport, ignoring the fact that one of the libraries is already built and the other one isn't. However, I'm not getting any link errors/warnings if I use only one global export.h header file, even though I expect them. Why?
 

Forum Broken?

10 February 2015 - 03:11 AM

Am I the only one who sees the forums like this?

http://i.imgur.com/ZE979Z5.jpg http://i.imgur.com/o82XDJr.jpg
http://i.imgur.com/LaqKKnT.jpg

It's been like this for the last 2 days for me. Every other website, every other forum, every other social platform, they all work for me. It's only GDNet that's doing this to me. Why?

Can someone explain this to me?

The homepage works, and browsing threads and boards works to some degree. By "some degree" I mean icons are missing, and weird stretching occurs, as can be seen here:

http://i.imgur.com/DRNtxPH.jpg

That last screenshot has always been the case for me, not only since the last 2 days. The forum has always stretched and missed icons like that.

$ uname -a
3.17.7-gentoo #1 SMP Sun Feb 1 05:45:15 CET 2015 x86_64 AMD Phenom™ II X6 1090T Processor AuthenticAMD GNU/Linux

$ eix google-chrome
[?] www-client/google-chrome
Available versions: ~40.0.2214.94_p1^msd {+plugins LINGUAS="+am +ar +bg +bn +ca +cs +da +de +el +en_GB +es +es_LA +et +fa +fi +fil +fr +gu +he +hi +hr +hu +id +it +ja +kn +ko +lt +lv +ml +mr +ms +nb +nl +pl +pt_BR +pt_PT +ro +ru +sk +sl +sr +sv +sw +ta +te +th +tr +uk +vi +zh_CN +zh_TW"}
Installed versions: 39.0.2171.95_p1^msd(18:24:17 19/12/14)(plugins LINGUAS="en_GB -am -ar -bg -bn -ca -cs -da -de -el -es -es_LA -et -fa -fi -fil -fr -gu -he -hi -hr -hu -id -it -ja -kn -ko -lt -lv -ml -mr -ms -nb -nl -pl -pt_BR -pt_PT -ro -ru -sk -sl -sr -sv -sw -ta -te -th -tr -uk -vi -zh_CN -zh_TW")

Generic events - Enforcing the correct function signatures.

18 January 2015 - 02:43 PM

I began development on a game written in C89 about a month ago. The design of this game is entirely centred around a plugin system which basically consists of a module loader, a service directory, and an events system.

The events system is horribly prone to human error and this is what I want to get some input on.

Consider the host application and two plugins, pluginA and pluginB. pluginA registers an event "foo" to the host application, and pluginB listens to that event. The flow of information, thus, looks like this:

         host app
      event dispatcher
        ^          \
       /            \
      /              v
   pluginA         pluginB
FIRE_EVENT(foo)  EVENT_LISTENER(on_foo)

The event system is implemented as follows:

/* generic function, any amount of arguments can be passed to a call of this function type (only works in C, not C++) */
typedef void (*event_listener_callback)();

struct event_t
{
    char* name;
    struct vector_t listeners; /* a vector of event_listener_t objects */
};

struct event_listener_t
{
    char* listener_name;
    event_listener_callback exec;
};

#define EVENT_H(event_name) extern struct event_t* event_name;
#define EVENT_C(event_name) struct event_t* event_name = NULL;

#define EVENT_FIRE0(event_name) \
    VECTOR_FOR_EACH((event_name)->listeners, struct event_listener_t, listener) \
    { \
        listener->exec(event_name); \
    }

#define EVENT_LISTENER0(name) \
    void name(const struct event_t* evt)

Note that there are macros for EVENT_FIRE1, EVENT_FIRE2, etc. depending on how many arguments the event wishes to send.

 

From pluginA's perspective, this is how it would register an event:

EVENT_C(evt_foo)

void pluginA_init(void)
{
    evt_foo = event_create("foo"); /* this returns a new event_t object */
}

From pluginB's perspective, this is how it would listen to the event "foo":

void register_events(void)
{
    event_register_listener("foo", on_foo); /* this adds the function "on_foo" to the corresponding event's listeners vector */
}

EVENT_LISTENER0(on_foo)
{
    puts("event foo received!");
}

The Problem

 

The issue with this system is that the receiving function "on_foo" could have any function signature, and it would compile anyway. Similarly, EVENT_FIRE could callback any number of arguments and yet it would compile anyway.

 

Furthermore, from pluginB's perspective, it's very hard to figure out what each event's callback function signature should be. The only place where it's defined is EVENT_FIRE0().

 

Is there any better way to implement this? Is there any way to enforce the programmer to match all function signatures correctly? The fact that the callback is delegated using a generic function probably makes this impossible, so I'm wondering if there's a better way to implement such a system?

 

[EDIT] How do I add the "C" prefix to my thread?


Very simple linking issue

10 January 2015 - 10:56 PM

Can someone tell me why GCC fails to link? It's 6 lines of code and two CMakeLists.txt files. If someone experienced with CMake could clone this and explain what the big issue is, I'd be glad.
https://github.com/TheComet93/cmake-sucks

I've wasted like an entire hour on this crap and it makes no sense. target_link_libraries() is being called in tests/CMakeLists.txt. The symbols exist (verified with readelf). Nothing appears wrong.

It's 6 lines of code yet it's so complicated.


PARTNERS