Exported DLL symbol validity
I'm building a cross-platform library which links to some other 3rd party libraries at run time (i.e. on Windows, the other libs will be available as DLLs whereas on Linux / OS-X etc they'd be shared objects, which are similar). For the sake of argument, one of those libraries is called "jack".
Obviously, our app can't guarantee which version of the other libs will be on the user's system (or even that they'll be installed at all). So our code is littered with statements like this:-
Code:
if (!jack_port_type_get_buffer_size) {
warning << _("This version of JACK is old - you should upgrade to a newer version") << endmsg;
} else {
some_var = jack_port_type_get_buffer_size();
}
We link to the latest version of jack, where that symbol is declared like so:-
Code:
size_t jack_port_type_get_buffer_size();
One problem is that it doesn't even seem to be an exported symbol (although that wouldn't affect the other platform builds). But apart from that, our customer might have an old copy of jack installed or even no copy! We seem to be making the assumption that if our customer has an up-to-date version, jack_port_type_get_buffer_size will be set to a valid address - but in all other case it'll be magically set to zero (there's nothing in our code that sets it to zero).
This whole strategy seems rather flaky to me. Am I worrying unnecessarily?
Re: Exported DLL symbol validity
and what happens if the symbol exists but it's still the wrong version? Your current version of jack may declare this symbol whereas previous versions don't - but future versions of jack will all declare this symbol so you won't be able to use this type of version checking to determine whether the client is using the lastest version or not. IMO the way you are doing the version checking is not good practice.
Re: Exported DLL symbol validity
Thanks 2kaud. That's not such a great problem as I don't think the intention is to verify that our customer is running the latest version per se - only that his version supports that particular function.
But I agree... this doesn't seem like good practice to me either. :(
I can't see why we're making the assumption that something will initialise that symbol to zero.
Re: Exported DLL symbol validity
I have to admit I wasn't able to fully understand the challenge and aspects like "it doesn't even seem to be an exported symbol" and "in all other case it'll be magically set to zero".
First of all, nothing there should be magically set, and all what you do you should do explicitly and on purpose.
No copy installed can be detected by LoadLibrary failure. You should not link your app with import library, as your customers with no copy installed won't be able even to run your app.
Now let's get to the point of magic:
Code:
size_t (*jack_port_type_get_buffer_size)() = NULL;
HINSTANCE hLib = LoadLibrary("magic_jack.dll");
if (hLib)
jack_port_type_get_buffer_size = (size_t (*)())GetProcAddress(hLib, "jack_port_type_get_buffer_size");
Now your jack_port_type_get_buffer_size is NULL (magic), or points to the proper dll export. In case it's not exported, there should be other way to set the pointer up via some other dll function that is exported.
And now about the version. This could be controlled via some dedicated function returning current version of the API the dll implements, or the version may be deduced from dll version info. Dedicated function seems to be more cross platform.
Re: Exported DLL symbol validity
It turns out that these are leftovers from a technique called weak exporting which is quite well established in Linux and OS-X. The addresses get obtained at run time (assuming that the symbol got found in some other compilation module) or otherwise, they get initialized to zero.
In fact according to that article, weak linking was also available in Win16 but was later abandoned by Microsoft. So it looks like we'll need to find some other technique that works for all platforms.
Re: Exported DLL symbol validity
Quote:
Originally Posted by
John E
In fact according to that article, weak linking was also available in Win16 but was later abandoned by Microsoft. So it looks like we'll need to find some other technique that works for all platforms.
I would think that the lowest common denominator would be the way to go.
1) Load the library at runtime (LoadLibrary), and check if it exists.
2) If so, query if the function exists (GetProcAddress).
I would be surprised if Linux/Unix didn't have a way to do this.
Regards,
Paul McKenzie