nodejs napi module did not self register - node.js

when i try to test nodejs N-API modules, the has a error to me:
my addon.c file is that:
#include <node_api.h>
napi_value HelloMethod (napi_env env, napi_callback_info info) {
napi_value world;
napi_create_string_utf8(env, "world", 5, &world);
return world;
}
void Init (napi_env env, napi_value exports, napi_value module, void* priv) {
napi_property_descriptor desc = { "hello", 0, HelloMethod, 0, 0, 0, napi_default, 0 };
napi_define_properties(env, exports, 1, &desc);
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
my binding.gyp file is:
{
"targets": [
{
"target_name": "addon",
"source": ["addon.c"]
}
]
}
and when i use require('./build/Release/addon') to call addon modules, the error info is :
Error: Module did not self-register.
at Object.Module._extensions..node (internal/modules/cjs/loader.js:707:18)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)
at Module.require (internal/modules/cjs/loader.js:626:17)
at require (internal/modules/cjs/helpers.js:20:18)
has anyone can help me? tanks

It seems the newer versions of node-addon-api has changed its API for the module registration/export. The data types that you are using will not work anymore either.
It is now done like so
#include <napi.h>
Napi::String HelloMethod(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
return Napi::String::New(env, "world");
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "hello"),
Napi::Function::New(env, HelloMethod));
return exports;
}
NODE_API_MODULE(addon, Init)
This works on node 11.10.1 and node-addon-api 1.6.2.

Try to change the file name "addon.c" to "addon.cpp", then rebuild and run.
See this: Successful compiling the Node module and "Module did not self-register."

Related

Setting up Typescript with expressjs import error

I have a folder structure as following
src
--/lib
----/errors
------/notFound.ts
in notFound.ts, I'm exporting this class
export abstract class HttpError extends Error {
abstract statusCode: number;
constructor(message: string) {
super(message);
Object.setPrototypeOf(this, HttpError.prototype);
}
abstract serializeErrors(): { message: string; field?: string }[];
}
export class NotFoundError extends HttpError {
statusCode = 404;
constructor() {
super('Route not found');
Object.setPrototypeOf(this, NotFoundError.prototype);
}
serializeErrors() {
return [{ message: 'The requested route is not Found' }];
}
}
Then in TSconfig.json, I have the path parameter set like this
"paths": {
"#/lib/*" : [
"src/lib/*"
],
"#/routes/*": [
"src/routes/*"
],
"*": [
"node_modules/*"
]
},
When i Import NotFoundError as follows, it results in error
import { NotFoundError } from '#/lib/errors/notFound';
Here's the error.
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
at Function.Module._load (internal/modules/cjs/loader.js:745:27)
at Module.require (internal/modules/cjs/loader.js:961:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.<anonymous> (/home/tuser/Projects/tpro/src/server/express.ts:5:1)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Module._compile (/home/tuser/Projects/tpro/node_modules/source-map-support/source-map-support.js:568:25)
at Module.m._compile (/tmp/ts-node-dev-hook-07042914060113459.js:69:33)
at Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at require.extensions..jsx.require.extensions..js (/tmp/ts-node-dev-hook-07042914060113459.js:114:20)
[ERROR] 16:40:04 Error: Cannot find module '#/lib/errors/notFound'
I have also tried imports like these
const { NotFoundError } = require('#/lib/errors/notFound')
const NotFoundError = require('#/lib/errors/notFound')
Both result in same error
What am i missing ?
Sorry, I initially wanted to post a comment but I don't have enough rep; instead, I've expanded what I know into a full answer in hopes it helps.
I've recently gone about with setting up Node + TypeScript + Express. The repo I made and was playing around with initially is here, but note that it's undocumented and the auxiliary configs aren't necessarily up to scratch. Also, apologies if the formatting of this answer is really unorthodox, and I hope linking to personal repos is not looked down on.
I'm uncertain if the paths in the tsconfig.json have anything to do with your issue; I've never used them, so I don't know. I would remove them for now.
As a preface, this is an imperfect solution.
For my Node/TypeScript/Express setup I had to do the following:
Set "type": "module" in package.json
Install required packages: > npm install ts-node ts-loader (I'm unsure if both are necessary, I believe they are though)
Add node --es-module-specifier-resolution=node --loader ts-node/esm ./src/server/express.ts (Presuming that express.ts is your entrypoint) as a command to your package.json and check if it works.
With what I understand, this works by specifically invoking ts-node with esm support, and it seems to work on Node 14 LTS and v16.9.1.
The command is rather hacky and will give you warnings about it being an experimental feature. I couldn't find any other solution for myself when (very stubbornly) using ESModules.
I've also used this command to use Webpack with TypeScript and ESM (that is, having a webpack.ts file with ESM imports) to compile TypeScript src files with ESM, as below (in package.json, from here):
"webpack-examples": "node --es-module-specifier-resolution=node --loader ts-node/esm node_modules/webpack-cli/bin/cli.js --config webpack.examples.ts --mode production",
expressjs doesnt support import statements yet. use require for eg const http = require("http");

Curry.js error when exporting a rescript function with more than 1 parameter using genType

When exporting a function with more than 1 parameter (2 or more) it throws the following error, which basically says there is an issue with the way we import curry.js. I am attaching an example and package versions below.
Error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: path/to/node_modules/rescript/lib/es6/curry.js
require() of ES modules is not supported.
require() of /path/to/node_modules/rescript/lib/es6/curry.js from /path/to/src/demo.gen.ts is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename curry.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /path/to/node_modules/rescript/lib/es6/package.json.
at new NodeError (node:internal/errors:329:5)
at Module._extensions..js (node:internal/modules/cjs/loader:1109:13)
at Object.require.extensions.<computed> [as .js] (/path/to/node_modules/ts-node/src/index.ts:851:44)
at Module.load (node:internal/modules/cjs/loader:972:32)
at Function.Module._load (node:internal/modules/cjs/loader:813:14)
at Module.require (node:internal/modules/cjs/loader:996:19)
at require (node:internal/modules/cjs/helpers:92:18)
at Object.<anonymous> (/path/to/src/demo.gen.ts:6:1)
at Module._compile (node:internal/modules/cjs/loader:1092:14)
at Module.m._compile (/path/to/node_modules/ts-node/src/index.ts:858:23)
Example
demo.res
#genType
let helloWord = (firstName: string, lastName: string): unit => {
Js.log("Hello " ++ firstName ++ " " ++ lastName)
}
demo.bs.js
// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';
function helloWord(firstName, lastName) {
console.log("Hello " + firstName + " " + lastName);
}
exports.helloWord = helloWord;
/* No side effect */
demo.gen.ts
/* TypeScript file generated from demo.res by genType. */
/* eslint-disable import/first */
// #ts-ignore: Implicit any on import
import * as Curry__Es6Import from 'rescript/lib/es6/curry.js';
const Curry: any = Curry__Es6Import;
// #ts-ignore: Implicit any on import
import * as demoBS__Es6Import from './demo.bs';
const demoBS: any = demoBS__Es6Import;
export const helloWord: (firstName:string, lastName:string) => void = function (Arg1: any, Arg2: any) {
const result = Curry._2(demoBS.helloWord, Arg1, Arg2);
return result
};
package.json
{
"ts-node": "^10.2.1",
"gentype": "^4.1.0",
"rescript": "^9.1.4",
"typescript": "^3.9.6"
}
Node Version
$ node -v
v15.11.0
OS
Manjaro Linux
After taking a look at this file in genType: https://github.com/rescript-association/genType/blob/fb6201266558a64d62441f7ac0d8d6652456397a/src/Config_.ml
I found this option
{
"gentypeconfig": {
"module": "commonjs",
}
}
setting that solves the issue :D
I could not found it anywhere else in rescript docs unfortunately :(

cannot open source file "node.h" in hello.cc

Node Version:v12.1.0
Platform:Mac osx
node-gyp:v5.0.3
I don't know if it's a problem or just a personal question 。as a nodejs addons beginner,I write a
hello.cc file,which as below:
#include <node.h>
#include <v8.h>
using namespace v8;
// 实现􏵹定义的方法
Handle<Value> SayHello(const Arguments &args)
{
HandleScope scope;
return scope.Close(String::New("Hello world!"));
}
// 给传入的目􏵺对象􏱭加sayHello()方法 void Init_Hello(Handle<Object>target) {
target->Set(String::NewSymbol("sayHello"),FunctionTemplate::New(SayHello)->GetFunction());
// 调用NODE_MODULE()方法将注􏵻方法定义􏵼内存中 NODE_MODULE(hello, Init_Hello)
and my binding.gyp is like this:
{
'targets': [
{
'target_name': 'hello', 'sources': [
'src/hello.cc'],
'conditions': [['OS == "mac"',
{
}
]],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}]
}
but the source code show Squiggles
and when I run node-gyp configure build
error shows:
all right version problem.
use nan.h fixed
https://github.com/nodejs/nan

javascript equivalent for python ctypes with node-gyp

I want to transform a python script into a javascript script. My python script loads a dll and use its API.
processings2D = ctypes.CDLL('processings2D.dll')
print(processings2D.ImageProcessor2DCreate())
I try do to the same with node-gyp but my script doesn't find the dll.
console.log(processings2D.ImageProcessor2DCreate());
^
TypeError: Cannot load processings2D.dll library
test.js
var processings2D = require('./build/Release/processings2D.node');
console.log(processings2D.ImageProcessor2DCreate());
addon.cc
#include <nan.h>
#include "processings2D/processings2D.h"
HINSTANCE hDLL = NULL;
typedef int(*Fn)();
void ImageProcessor2DCreate(const Nan::FunctionCallbackInfo<v8::Value>& info) {
hDLL = LoadLibrary("processings2D.dll");
if(!hDLL)
{
Nan::ThrowTypeError("Cannot load processings2D.dll library");
return;
}
Fn fn = (Fn)GetProcAddress(hDLL, "ImageProcessor2DCreate");
if (!fn) {
Nan::ThrowTypeError("Could not load ImageProcessor2DCreate function");
FreeLibrary(hDLL);
return;
}
info.GetReturnValue().Set(Nan::New(fn()));
}
void Init(v8::Local<v8::Object> exports) {
exports->Set(Nan::New("ImageProcessor2DCreate").ToLocalChecked(), Nan::New<v8::FunctionTemplate>(ImageProcessor2DCreate)->GetFunction());
}
NODE_MODULE(twoD, Init)
binding.gyp
{
"targets": [
{
"target_name": "processings2D",
"sources": [
"addon.cc"
],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}
]
}
dll is in the Release folder /build/Release/processings2D.dll
Am I in the right direction ?
The solution was really simple :
My dll was a 32 bit version, so I should build my module with the 32 bit arch flag and execute my test with the 32 bit version of node.
node-gyp clean configure --arch=ia32 build
"C:\Program Files (x86)\nodejs\node.exe" test.js

Run CImg library with node-gyp error

I want to use CImg library to deal images in node.js,so i write an node addon to do it.
The compile is success, i run node-gyp build commond, that's ok.
But when i run the node program,the follow error occurs:
[root#localhost hcaptha]# node index.js
module.js:485
process.dlopen(filename, module.exports);
^
Error: /usr/local/nodejs/hcaptha/build/Release/hcaptha.node: undefined symbol: XSendEvent
at Object.Module._extensions..node (module.js:485:11)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object.<anonymous> (/usr/local/nodejs/hcaptha/lib/hcap.js:1:75)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
the binding.gyp file is:
{
"targets":[
{
"target_name": "hcaptha",
"sources": [ "addon/hcaptha.cc" ,"addon/cap.cc"],
'cflags': ['-fexceptions','-O2','-Dcimg_use_png'],//the configure using CImg lib
'cflags_cc': ['-fexceptions','-O2','-Dcimg_use_png']
}
]
}
cap.cc code:
#include <node.h>
#include <string>
#include <iostream>
#include "cap.h"
#include "CImg-1.5.3/CImg.h"
using namespace v8;
Handle<Value> cap::create(const Arguments& args) {//create an image
HandleScope scope;
using namespace cimg_library;
CImg<unsigned char> captcha(256,64,1,3,0);//delete this line run ok!
return scope.Close(Boolean::New(1));
}
cap::cap(){};
cap::~cap(){};
index.js code:
var obj = require('../build/Release/hcaptha.node');
anyone can help me?
I finally find the result.
add line "libraries":['-lX11'] into the binding.gyp file,that's ok!
new binding.gyp file like this:
{
"targets":[
{
"target_name": "hcaptha",
"sources": [ "addon/hcaptha.cc" ,"addon/cap.cc"],
"cflags": ['-fexceptions','-O2','-Dcimg_use_png'],
"cflags_cc": ['-fexceptions','-O2','-Dcimg_use_png'],
"libraries":['-lX11']
}
]
}

Resources