Created
September 29, 2011 17:45
-
-
Save jonforums/1251389 to your computer and use it in GitHub Desktop.
Experimenting with exporting symbols from a multi-platform C++ executable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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