public
Created

Experimenting with exporting symbols from a multi-platform C++ executable

  • Download Gist
vm.cpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// 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;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.