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::NewStringType;
21 using v8::String;
22 using v8::Value;
23
24 typedef const char* (*ping)(void);
25
26 static ping ping_func;
27
LoadLibrary(const FunctionCallbackInfo<Value> & args)28 void LoadLibrary(const FunctionCallbackInfo<Value>& args) {
29 const String::Utf8Value filename(args.GetIsolate(), args[0]);
30 void* handle = dlopen(*filename, RTLD_LAZY);
31 if (handle == nullptr) fprintf(stderr, "%s\n", dlerror());
32 assert(handle != nullptr);
33 ping_func = reinterpret_cast<ping>(dlsym(handle, "dlopen_ping"));
34 assert(ping_func != nullptr);
35 }
36
Ping(const FunctionCallbackInfo<Value> & args)37 void Ping(const FunctionCallbackInfo<Value>& args) {
38 Isolate* isolate = args.GetIsolate();
39 assert(ping_func != nullptr);
40 args.GetReturnValue().Set(String::NewFromUtf8(
41 isolate, ping_func(), NewStringType::kNormal).ToLocalChecked());
42 }
43
init(Local<Object> exports)44 void init(Local<Object> exports) {
45 NODE_SET_METHOD(exports, "load", LoadLibrary);
46 NODE_SET_METHOD(exports, "ping", Ping);
47 }
48
49 NODE_MODULE(NODE_GYP_MODULE_NAME, init)
50
51 } // anonymous namespace
52
53 #endif // _WIN32
54