views:

195

answers:

1

Is there a cross platform way to selectively export certain functions and structs from a C project which builds a shared library?

I want to do in a way that does not require a specific build system (the visibility should be defined in the code, eg as a macro), and in a way which both GCC and MSVC can understand.

Thank you.

+1  A: 

Strictly no, of course, because the toolchains aren't the same.

But people do this. The complexities are that in windows, you need to specifically tag the declarations of functions you want exported from a DLL with __declspec(dllexport) in the location in the library where the function is defined and __declspec(dllimport) in the locations in client code where the funciton is referenced. Because standard C practice has only one declaration in a single header file, this means that you generally need to do some macro work to have a single prefix that works in both locations. It seems like every project picks its own standard for this.

On the Unix side, you don't need to tag exports at all, which is nice. This is because every non-static function is exported by default, which is not so nice. Often you can get away with this as long as your non-public/non-static symbols have sane prefixes, which is what most projects seem to do. If you need finer control over your exported symbols, you can use a Solaris-style "mapfile" with the GNU linker's --version-script (-M under solaris) argument to define explicitly which symbols should appear in the external namespace.

There are a few more gotchas between the platforms, like the way the per-library global namespace works and the handling of startup/shutdown code. Basically, it's a rats nest that can't be sanely explained in a post this short, but as long as you're careful that your library contains simple functions and your namespace doesn't pollute, you shouldn't have much trouble. Look to some of the more popular cross-platform shared libraries (e.g. Qt, Glib/Gtk+, anything distributed with msys, etc...) for guidance.

Andy Ross