1 #include <node.h>
2 #include <v8.h>
3
4 #ifndef _WIN32
5
6 #include <dlfcn.h>
7
8 extern "C"
9 __attribute__((visibility("default")))
dlopen_pong(void)10 const char* dlopen_pong(void) {
11 return "pong";
12 }
13
14 namespace {
15
16 using v8::FunctionCallbackInfo;
17 using v8::Isolate;
18 using v8::Local;
19 using v8::Object;
20 using v8::String;
21 using v8::Value;
22
23 typedef const char* (*ping)(void);
24
25 static ping ping_func;
26
LoadLibrary(const FunctionCallbackInfo<Value> & args)27 void LoadLibrary(const FunctionCallbackInfo<Value>& args) {
28 const String::Utf8Value filename(args.GetIsolate(), args[0]);
29 void* handle = dlopen(*filename, RTLD_LAZY);
30 if (handle == nullptr) fprintf(stderr, "%s\n", dlerror());
31 assert(handle != nullptr);
32 ping_func = reinterpret_cast<ping>(dlsym(handle, "dlopen_ping"));
33 assert(ping_func != nullptr);
34 }
35
Ping(const FunctionCallbackInfo<Value> & args)36 void Ping(const FunctionCallbackInfo<Value>& args) {
37 Isolate* isolate = args.GetIsolate();
38 assert(ping_func != nullptr);
39 args.GetReturnValue().Set(String::NewFromUtf8(
40 isolate, ping_func()).ToLocalChecked());
41 }
42
init(Local<Object> exports)43 void init(Local<Object> exports) {
44 NODE_SET_METHOD(exports, "load", LoadLibrary);
45 NODE_SET_METHOD(exports, "ping", Ping);
46 }
47
48 NODE_MODULE(NODE_GYP_MODULE_NAME, init)
49
50 } // anonymous namespace
51
52 #endif // _WIN32
53