Nodejs interoperar com C++ shared library (DLL, SO)

280 views
Skip to first unread message

Saraiva Silva

unread,
Feb 14, 2016, 2:45:58 PM2/14/16
to Node.js Brasil
O addon node-ffi possibilita que aplicações nodejs acessem bibliotecas dinâmicas (Shared Libraries), as famigeradas dll do windows, .so no caso do linux. Queria saber se alguém tem experiência no uso desse addon, e possa me relatar qual foi a experiência, ou seja, quais foram as dificuldades, e bugs (se houveram). Cite o projeto e qual papel a dll ou .so desempenhavam. Por exemplo minha ideia é usar Electron como front-end de uma aplicação C++, onde o back-end ficará todo em uma Shared Library (.SO).

Gustavo Duarte

unread,
Feb 17, 2016, 9:31:22 PM2/17/16
to nod...@googlegroups.com
Olá Saraiva,

Eu não tenho experiência com o node-ffi, mas tenho bastante experiência com add-ons em C++. O tradeoff básico é que o node-ffi permite que você invoque as funções sem nenhum código boilerplate, mas com muito menos performance. Os add-ons oferecem ótima performance, mas te obrigam a escrever boilerplate para conectar o JS ao seu C++.

No geral, não tive nenhum problema em integrar Node com C++. Tudo funciona lindamente: a libuv, o V8, e as chamadas de função do JS para o C++. Para compartilhar dados, basta alocar via V8 no seu C++ e boas. Para te dar uma idéia da forma da solução, alguns exemplos de código:

1. Inicialização do add-on, basicamente expões uma "classe" de JS chamada Index para o JS, cujo protótipo tem duas funções ("open" e "suggest"):

void v8Index::initModule(Handle<Object> exports, Handle<Object> module)
{
    Isolate* isolate = Isolate::GetCurrent();

    // Prepare constructor template
    Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, constructor);
    tpl->SetClassName(String::NewFromUtf8(isolate, "Index"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    // Prototype
    NODE_SET_PROTOTYPE_METHOD(tpl, "suggest", suggest);
    NODE_SET_PROTOTYPE_METHOD(tpl, "open", open);

    constructorHandle.Reset(isolate, tpl->GetFunction());

    NODE_SET_METHOD(exports, "loadIndex", loadIndex);
}

2. Aqui está a definição dessa função "suggest", para que você tenha uma idéia do que involve:

void v8Index::suggest(const FunctionCallbackInfo<Value>& args)
{
    do_search(args, Search_op::suggest);
}

Ou seja, você basicamente usa umas macros que o Node provê, tipo essa "NODE_SET_PROTOTYPE_METHOD" e fogo na bomba! É bem fácil colocar o Node falando com seu código. E você pode compilar seu add-on em C++ linkado com qualquer lib, shared ou estática, e tudo funciona. Já usei várias libs shared, nunca ouve problema.

Para retornar dados para o JS, você aloca coisas no V8 e as retorna. Por exemplo, aqui está uma função que pega um vector em C++ e o retorna para JS:

static Handle<Array> v8_array(
    Isolate* isolate,
    const vector<int>& vector
)
{
    Handle<Array> array = Array::New(isolate, vector.size());

    for(size_t i = 0; i < vector.size(); i++) {
        array->Set(i, v8Integer(isolate, vector[i]));
    }

    return array;
}

Onde v8Integer é esse helperzinho aqui:

    inline v8::Local<v8::Integer> v8Integer(
        Isolate* isolate, const int i)
    {
        return v8::Integer::New(isolate, i);
    }


Bom, desculpe o flood de código, mas espero que ajude. Se você decidir prosseguir com o add-on, é bem tranquilo, e posso ajudar. Caso o node-ffi faça mais sentido, boa sorte ai :)




2016-02-14 12:39 GMT-07:00 Saraiva Silva <matheus...@gmail.com>:
O addon node-ffi possibilita que aplicações nodejs acessem bibliotecas dinâmicas (Shared Libraries), as famigeradas dll do windows, .so no caso do linux. Queria saber se alguém tem experiência no uso desse addon, e possa me relatar qual foi a experiência, ou seja, quais foram as dificuldades, e bugs (se houveram). Cite o projeto e qual papel a dll ou .so desempenhavam. Por exemplo minha ideia é usar Electron como front-end de uma aplicação C++, onde o back-end ficará todo em uma Shared Library (.SO).

--
Você recebeu essa mensagem porque está inscrito no grupo "Node.js Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para nodebr+un...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

Gustavo Duarte

unread,
Feb 17, 2016, 9:32:09 PM2/17/16
to nod...@googlegroups.com
"No geral, não tive nenhum problema em integrar Node com C++."

Usando add-ons. Oops ;)

diego nunes

unread,
Feb 17, 2016, 10:31:13 PM2/17/16
to nod...@googlegroups.com
Gustavo, parabéns pela resposta, super completa, com exemplos, e
muito útil :) Salvei até aqui como referência pra quando eu precisar.
--
diego nunes
dnunes.com

Gustavo Duarte

unread,
Feb 18, 2016, 9:25:10 AM2/18/16
to nod...@googlegroups.com
Diego,

Bom demais que foi útil! Se eu puder ajudar aqui na lista quanto à add-ons ou libuv, só falar.

E mais um typo: "nunca _h_ouve problemas", e não "ouve problemas". hahah :P  Queria que o "undo" do gmail fosse um pouco mais longo.

--
Você está recebendo esta mensagem porque se inscreveu no grupo "Node.js Brasil" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para nodebr+un...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages