Skip to content

Instantly share code, notes, and snippets.

@jonforums
Created September 29, 2011 17:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonforums/1251389 to your computer and use it in GitHub Desktop.
Save jonforums/1251389 to your computer and use it in GitHub Desktop.
Experimenting with exporting symbols from a multi-platform C++ executable
// Testing symbol visibility from a C++ executable
// file: vm.cpp
// revision: 09/29/2011 1:42:06 PM
//
// build via:
// export demangled symbols (mingw): g++ -DRBX_API_EXPORT -o vm.exe vm.cpp
// force export (mangled & demangled) symbols (*nix): g++ -o vm vm.cpp -Wl,-export-dynamic
// forced (mangled & demangled) symbol export (mingw): g++ -o vm.exe vm.cpp -Wl,-export-all-symbols
// export no symbols (mingw, *nix): g++ -o vm[.exe] vm.cpp
//
// verify exported symbols (mingw): objdump -p vm.exe | less
// verify exported symbols (*nix): objdump -T vm | less
//
// TODO
// * verify link from DLL behavior on mingw and *nix
#include <iostream>
using namespace std;
#if defined(_WIN32)
# if defined(RBX_API_EXPORT)
# define RBX_API(type) extern "C" __declspec(dllexport) type
# elif defined(RBX_API_IMPORT)
# define RBX_API(type) extern "C" __declspec(dllimport) type
# else
# define RBX_API(type) extern "C" type
# endif
#else // not _WIN32
/* TODO verify no need to do anything non-default like this for *nix
# if __GNUC__ >= 4
# if defined(RBX_API_EXPORT) || defined(RBX_API_IMPORT)
# define RBX_API(type) extern "C" __attribute__((__visibility__("default"))) type
# elif !defined(RBX_API_EXPORT) && !defined(RBX_API_IMPORT)
# define RBX_API(type) extern "C" __attribute__((__visibility__("hidden"))) type
# endif
# else
# define RBX_API(type) extern "C" type
# endif
*/
# define RBX_API(type) extern "C" type
#endif
namespace rubinius {
namespace capi {
RBX_API(void) capi_raise_runtime_error(const char* reason)
{
cout << "[RBX_API(void)] 'rubinius::capi::capi_rais_runtime_error' raising runtime error: " << reason << endl;
}
void capi_raise_backend()
{
cout << "'rubinius::capi::capi_raise_backend' internal raising impl" << endl;
}
}
}
RBX_API(int) rb_scan_args()
{
cout << "[RBX_API(int)] non-namespaced 'rb_scan_args' says hi" << endl;
return 0;
}
RBX_API(void) rb_str_new()
{
cout << "[RBX_API(void)] non-namespaced 'rb_str_new' says hi" << endl;
}
namespace {
void foo()
{
cout << "private namespaced 'foo' says hi" << endl;
}
}
void bar()
{
cout << "non-namespaced, non-static 'bar' says hi" << endl;
}
static void baz()
{
cout << "non-namespaced, static 'baz' says hi" << endl;
}
int main(int argc, char **argv)
{
foo();
bar();
baz();
rb_scan_args();
rb_str_new();
rubinius::capi::capi_raise_runtime_error("uh-oh");
rubinius::capi::capi_raise_backend();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment