Skip to content

Instantly share code, notes, and snippets.

@icebarf
Last active October 17, 2025 14:01
Show Gist options
  • Save icebarf/835454c7b3b2d722777226a4c203af6b to your computer and use it in GitHub Desktop.
Save icebarf/835454c7b3b2d722777226a4c203af6b to your computer and use it in GitHub Desktop.
shared object stuff
$ g++ -o libcode.so code.cpp -ldl -rdynamic -shared -fPIC -std=c++20
$ g++ -o main main.cpp -rdynamic -std=c++20 -Os

The -rdynamic flag when compiling the executable adds the unused symbols to the table so we can use the definition from the main/executable file in the shared object's foo() call.

#include <string>
extern "C" void print(std::string);
extern "C" void foo() { print("foo called print but without definition"); }
#include <dlfcn.h>
#include <format>
#include <functional>
#include <iostream>
#include <string>
extern "C" void print(std::string s) { std::cout << s << '\n'; }
int main() {
void *shared_object = dlopen("./libcode.so", RTLD_LAZY | RTLD_GLOBAL);
if (shared_object == nullptr) {
std::cout << std::format("Error loading shared object: {}\n", dlerror());
return 1;
}
std::function<void()> so_foo =
reinterpret_cast<void (*)()>(dlsym(shared_object, "foo"));
if (so_foo == nullptr) {
std::cout << std::format("Error finding symbol \"print\": {}\n", dlerror());
return 2;
}
so_foo();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment