From 0e724c9126e816823c33d780ce46b1c812ed0ee5 Mon Sep 17 00:00:00 2001 From: Misery42 Date: Sat, 17 Aug 2019 22:10:06 +0100 Subject: [PATCH 1/6] Added HelloWorld example as requested * fixes #83 * NAPI example for working with UTF-8 encoded strings --- 1_hello_world/napi/{ => example1}/binding.gyp | 0 1_hello_world/napi/{ => example1}/hello.cc | 0 1_hello_world/napi/{ => example1}/hello.js | 0 .../napi/{ => example1}/package.json | 0 .../napi/example2/libHelloWorld/.gitignore | 1 + .../napi/example2/libHelloWorld/binding.gyp | 9 +++ .../napi/example2/libHelloWorld/build.sh | 5 ++ .../napi/example2/libHelloWorld/lib/build.sh | 1 + .../libHelloWorld/lib/compileLibHelloWorld.sh | 1 + .../libHelloWorld/lib/libHelloWorld.c | 10 +++ .../libHelloWorld/lib/libHelloWorld.h | 6 ++ .../napi/example2/libHelloWorld/module.js | 5 ++ .../napi/example2/libHelloWorld/package.json | 12 ++++ .../napi/example2/libHelloWorld/src/module.c | 62 +++++++++++++++++++ 14 files changed, 112 insertions(+) rename 1_hello_world/napi/{ => example1}/binding.gyp (100%) rename 1_hello_world/napi/{ => example1}/hello.cc (100%) rename 1_hello_world/napi/{ => example1}/hello.js (100%) rename 1_hello_world/napi/{ => example1}/package.json (100%) create mode 100644 1_hello_world/napi/example2/libHelloWorld/.gitignore create mode 100644 1_hello_world/napi/example2/libHelloWorld/binding.gyp create mode 100755 1_hello_world/napi/example2/libHelloWorld/build.sh create mode 100755 1_hello_world/napi/example2/libHelloWorld/lib/build.sh create mode 100755 1_hello_world/napi/example2/libHelloWorld/lib/compileLibHelloWorld.sh create mode 100644 1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.c create mode 100644 1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.h create mode 100644 1_hello_world/napi/example2/libHelloWorld/module.js create mode 100644 1_hello_world/napi/example2/libHelloWorld/package.json create mode 100644 1_hello_world/napi/example2/libHelloWorld/src/module.c diff --git a/1_hello_world/napi/binding.gyp b/1_hello_world/napi/example1/binding.gyp similarity index 100% rename from 1_hello_world/napi/binding.gyp rename to 1_hello_world/napi/example1/binding.gyp diff --git a/1_hello_world/napi/hello.cc b/1_hello_world/napi/example1/hello.cc similarity index 100% rename from 1_hello_world/napi/hello.cc rename to 1_hello_world/napi/example1/hello.cc diff --git a/1_hello_world/napi/hello.js b/1_hello_world/napi/example1/hello.js similarity index 100% rename from 1_hello_world/napi/hello.js rename to 1_hello_world/napi/example1/hello.js diff --git a/1_hello_world/napi/package.json b/1_hello_world/napi/example1/package.json similarity index 100% rename from 1_hello_world/napi/package.json rename to 1_hello_world/napi/example1/package.json diff --git a/1_hello_world/napi/example2/libHelloWorld/.gitignore b/1_hello_world/napi/example2/libHelloWorld/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/1_hello_world/napi/example2/libHelloWorld/binding.gyp b/1_hello_world/napi/example2/libHelloWorld/binding.gyp new file mode 100644 index 00000000..9ed16fd5 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/binding.gyp @@ -0,0 +1,9 @@ +{ + "targets": [ + { + "target_name": "module", + "sources": [ "./src/module.c" ], + "libraries": [ "/usr/lib/libHelloWorld.so" ] + } + ] +} diff --git a/1_hello_world/napi/example2/libHelloWorld/build.sh b/1_hello_world/napi/example2/libHelloWorld/build.sh new file mode 100755 index 00000000..106d8ea8 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/build.sh @@ -0,0 +1,5 @@ +sudo cp ./lib/libHelloWorld.so /usr/lib/ && \ +sudo cp ./lib/libHelloWorld.h /usr/include/ && \ +node-gyp configure build && \ +sudo node module.js +exit 0 diff --git a/1_hello_world/napi/example2/libHelloWorld/lib/build.sh b/1_hello_world/napi/example2/libHelloWorld/lib/build.sh new file mode 100755 index 00000000..57da271b --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/lib/build.sh @@ -0,0 +1 @@ +./compileLibHelloWorld.sh && sudo cp libHelloWorld.so /usr/lib && sudo cp libHelloWorld.h /usr/include diff --git a/1_hello_world/napi/example2/libHelloWorld/lib/compileLibHelloWorld.sh b/1_hello_world/napi/example2/libHelloWorld/lib/compileLibHelloWorld.sh new file mode 100755 index 00000000..3d7a2680 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/lib/compileLibHelloWorld.sh @@ -0,0 +1 @@ +gcc -o libHelloWorld.so -shared libHelloWorld.c diff --git a/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.c b/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.c new file mode 100644 index 00000000..fb384197 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.c @@ -0,0 +1,10 @@ +#include "libHelloWorld.h" +#include + +char * HelloWorldConcat (char * cHello, char * cWorld){ + char * cHelloWorld = NULL; + + cHelloWorld = strcat(cHello, cWorld); + + return cHelloWorld; +} diff --git a/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.h b/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.h new file mode 100644 index 00000000..1594906f --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/lib/libHelloWorld.h @@ -0,0 +1,6 @@ +#ifndef __HELLOWORLDSDK_TYPES_H__ +#define __HELLOWORLDSDK_TYPES_H__ + +char * HelloWorldConcat (char * cHello, char * cWorld); + +#endif diff --git a/1_hello_world/napi/example2/libHelloWorld/module.js b/1_hello_world/napi/example2/libHelloWorld/module.js new file mode 100644 index 00000000..027e1798 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/module.js @@ -0,0 +1,5 @@ +const addon = require('./build/Release/module'); +const hello = "Hello"; +const world = "World"; + +console.log(`${hello} concat ${world} equals`, addon.helloWorldConcat(hello, world)); diff --git a/1_hello_world/napi/example2/libHelloWorld/package.json b/1_hello_world/napi/example2/libHelloWorld/package.json new file mode 100644 index 00000000..f17105f2 --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/package.json @@ -0,0 +1,12 @@ +{ + "name": "helloworldlib", + "version": "1.0.0", + "description": "NAPI Test", + "main": "module.js", + "scripts": { + "start": "node-gyp configure build && node module.js", + "test": "console.log(\"Hello World!\");" + }, + "author": "Steven Klein", + "license": "MIT" +} diff --git a/1_hello_world/napi/example2/libHelloWorld/src/module.c b/1_hello_world/napi/example2/libHelloWorld/src/module.c new file mode 100644 index 00000000..d4dce95e --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/src/module.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include "libHelloWorld.h" + +napi_value hello_world_concat (napi_env env, napi_callback_info info) { + + size_t argc = 2; + size_t iTotalSize = 0; + + napi_value args[2]; + + napi_get_cb_info(env, info, &argc, args, NULL, NULL); + + size_t str_size; + size_t str_size_read; + // Extract only argument 2 "World" (args[1]) + napi_get_value_string_utf8(env, args[0], NULL, 0, &str_size); + char * cHello; + cHello = (char*)calloc(str_size + 1, sizeof(char)); + str_size = str_size + 1; + napi_get_value_string_utf8(env, args[0], cHello, str_size, &str_size_read); + + iTotalSize = iTotalSize + str_size_read; + + napi_get_value_string_utf8(env, args[1], NULL, 0, &str_size); + char * cWorld; + cWorld = (char*)calloc(str_size + 1, sizeof(char)); + str_size = str_size + 1; + napi_get_value_string_utf8(env, args[1], cWorld, str_size, &str_size_read); + + iTotalSize = iTotalSize + str_size_read; + + char * cResult = HelloWorldConcat(cHello, cWorld); + //printf("%s, %s \n", "Hello", cResult); // Debug output: Hello, world + + napi_value result; + + napi_create_string_utf8(env, cResult, iTotalSize, &result); + free(cHello); + free(cWorld); + return result; +} + +napi_value Init(napi_env env, napi_value exports) { + napi_status status; + napi_value fn; + + status = napi_create_function(env, NULL, 0, hello_world_concat, NULL, &fn); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Unable to wrap native function"); + } + + status = napi_set_named_property(env, exports, "helloWorldConcat", fn); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Unable to populate exports"); + } + + return exports; +} + +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) From 5f0dfdfffc9f56e78245b264137bc1dae94f4c61 Mon Sep 17 00:00:00 2001 From: Misery42 <42983952+Misery42@users.noreply.github.com> Date: Sat, 17 Aug 2019 23:49:49 +0200 Subject: [PATCH 2/6] Update build.sh Added execution of ./lib/buid.sh --- 1_hello_world/napi/example2/libHelloWorld/build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/1_hello_world/napi/example2/libHelloWorld/build.sh b/1_hello_world/napi/example2/libHelloWorld/build.sh index 106d8ea8..38688dfb 100755 --- a/1_hello_world/napi/example2/libHelloWorld/build.sh +++ b/1_hello_world/napi/example2/libHelloWorld/build.sh @@ -1,5 +1,4 @@ -sudo cp ./lib/libHelloWorld.so /usr/lib/ && \ -sudo cp ./lib/libHelloWorld.h /usr/include/ && \ +sudo ./lib/build.sh && \ node-gyp configure build && \ sudo node module.js exit 0 From 568e8c2c3d5f226fc3bfb54d77aa31c11d00b083 Mon Sep 17 00:00:00 2001 From: Misery42 <42983952+Misery42@users.noreply.github.com> Date: Sat, 17 Aug 2019 23:54:18 +0200 Subject: [PATCH 3/6] Create README.md inital upload --- 1_hello_world/napi/example2/libHelloWorld/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 1_hello_world/napi/example2/libHelloWorld/README.md diff --git a/1_hello_world/napi/example2/libHelloWorld/README.md b/1_hello_world/napi/example2/libHelloWorld/README.md new file mode 100644 index 00000000..6c7e58ba --- /dev/null +++ b/1_hello_world/napi/example2/libHelloWorld/README.md @@ -0,0 +1,6 @@ +This example covers handling UTF-8 encoded strings as parameters for an external C library + +Execute build.sh it will execute ./lib/build.sh wich compiles die libHelloWorld.so and copy it with the header to /usr/lib and /usr/include +After that it ties to build die NAPI Module and execute the module.js. + +The output should be: "Hello concat World equals HelloWorld" From 77ec5f91af57560efb8bfda0bc4d6d4b33bfa715 Mon Sep 17 00:00:00 2001 From: Misery42 <42983952+Misery42@users.noreply.github.com> Date: Sun, 18 Aug 2019 00:03:51 +0200 Subject: [PATCH 4/6] Update module.c --- 1_hello_world/napi/example2/libHelloWorld/src/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1_hello_world/napi/example2/libHelloWorld/src/module.c b/1_hello_world/napi/example2/libHelloWorld/src/module.c index d4dce95e..cafc425b 100644 --- a/1_hello_world/napi/example2/libHelloWorld/src/module.c +++ b/1_hello_world/napi/example2/libHelloWorld/src/module.c @@ -14,7 +14,7 @@ napi_value hello_world_concat (napi_env env, napi_callback_info info) { size_t str_size; size_t str_size_read; - // Extract only argument 2 "World" (args[1]) + napi_get_value_string_utf8(env, args[0], NULL, 0, &str_size); char * cHello; cHello = (char*)calloc(str_size + 1, sizeof(char)); From dc31322e685a2a259c59a47d24bf02f91e4d68a0 Mon Sep 17 00:00:00 2001 From: Akito13 Date: Sun, 18 Aug 2019 00:08:40 +0200 Subject: [PATCH 5/6] Initiating walkthrough --- .../napi/example2/libHelloWorld/README.md | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/1_hello_world/napi/example2/libHelloWorld/README.md b/1_hello_world/napi/example2/libHelloWorld/README.md index 6c7e58ba..fff2ef65 100644 --- a/1_hello_world/napi/example2/libHelloWorld/README.md +++ b/1_hello_world/napi/example2/libHelloWorld/README.md @@ -1,6 +1,25 @@ -This example covers handling UTF-8 encoded strings as parameters for an external C library +This example covers handling of UTF-8 encoded strings as parameters for an external C library. It goes beyond the demonstration of the initial example, seen in the `example1` folder. Combining both examples together should result in a clearer and more complete view of how to use the NAPI for this type of use cases. -Execute build.sh it will execute ./lib/build.sh wich compiles die libHelloWorld.so and copy it with the header to /usr/lib and /usr/include -After that it ties to build die NAPI Module and execute the module.js. +1. Dependencies +``` +build-essential +python2 +nodejs +node-gyp +``` +Installable on Debian-based systems like this: +``` +sudo apt install build-essential python2 nodejs node-gyp +``` -The output should be: "Hello concat World equals HelloWorld" +2. Building and running the project: +``` +cd node-addon-examples/1_hello_world/napi/example2/libHelloWorld/ +./build.sh +``` +This will execute `build.sh` which will compile `libHelloWorld.so` within `lib/`. Afterwards, the shared object will be opied to `/usr/lib` and its header will be copied to `/usr/include`. Done that, the NAPI module will be built and `module.js` will be executed. + +3. Once the previous steps were finished successfully, the output should be as follows: +``` +Hello concat World equals HelloWorld +``` From 1459e214735dafc912c038b21ffc1cc25f95c4cf Mon Sep 17 00:00:00 2001 From: Akito13 Date: Sun, 18 Aug 2019 00:13:16 +0200 Subject: [PATCH 6/6] Typo --- 1_hello_world/napi/example2/libHelloWorld/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1_hello_world/napi/example2/libHelloWorld/README.md b/1_hello_world/napi/example2/libHelloWorld/README.md index fff2ef65..cff23ffb 100644 --- a/1_hello_world/napi/example2/libHelloWorld/README.md +++ b/1_hello_world/napi/example2/libHelloWorld/README.md @@ -2,7 +2,7 @@ This example covers handling of UTF-8 encoded strings as parameters for an exter 1. Dependencies ``` -build-essential +gcc python2 nodejs node-gyp @@ -17,7 +17,7 @@ sudo apt install build-essential python2 nodejs node-gyp cd node-addon-examples/1_hello_world/napi/example2/libHelloWorld/ ./build.sh ``` -This will execute `build.sh` which will compile `libHelloWorld.so` within `lib/`. Afterwards, the shared object will be opied to `/usr/lib` and its header will be copied to `/usr/include`. Done that, the NAPI module will be built and `module.js` will be executed. +This will execute `build.sh` which will compile `libHelloWorld.so` within `lib/`. Afterwards, the shared object will be copied to `/usr/lib` and its header will be copied to `/usr/include`. Done that, the NAPI module will be built and `module.js` will be executed. 3. Once the previous steps were finished successfully, the output should be as follows: ```