Предоставлять функциональность c-библиотеки узлу

Я работаю над использованием библиотеки c в своем проекте node. После небольшого исследования я нашел node-gyp.

Мне удалось успешно выполнить пример, но когда я пытался использовать сторонние функции библиотеки c в коде, это давало мне ошибку связывания во время выполнения.

Библиотеку можно найти здесь http://bibutils.refbase.org/bibutils_3.40_src.tgz

Я скомпилировал библиотеку самостоятельно, чтобы иметь объекты *.a

Я использую следующий пример: https://github.com/nodejs/node-addon-examples/tree/master/5_function_factory/node_0.12

Итак, у меня есть следующие вопросы, как я могу сделать вывод

  • Должен ли я преобразовать бибутилы из make в gyp?
  • Должен ли я конвертировать каждый исходный файл для работы с V8? Я не знаю, как это сделать.
  • Как я могу легко связать этот проект для работы с node-gyp с меньшим количеством шума?

Подробности, связанные со сценарием, можно найти ниже. папка bibutils помещается вместе с addon.cc

binding.gyp выглядит так

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon.cc" ],
      "include_dirs": ["bibutils/lib"],
      "library_dirs": ["bibutils/lib/libbibutil.a","bibutils/lib/libbibprogs.a"]
    }
  ]
}

измененный файл addon.cc

#include <node.h>
#include "bibutils.h"
#include "bibprogs.h"

using namespace v8;

void MyFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
      /****This is not production code just to check the execution***/
      bibl b;   
      bibl_init( &b );
      bibl_free( &b );
      /**************************************************************/
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
}

void CreateFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);
  Local<Function> fn = tpl->GetFunction();

  // omit this to make it anonymous
  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));

  args.GetReturnValue().Set(fn);
}

Результат компиляции

user1@ubuntu:~/node-addon-examples/5_function_factory/node_0.12$ npm install

> [email protected] install /home/user1/node-addon-examples/5_function_factory/node_0.12
> node-gyp rebuild

make: Entering directory `/home/user1/node-addon-examples/5_function_factory/node_0.12/build'
  CXX(target) Release/obj.target/addon/addon.o
  SOLINK_MODULE(target) Release/obj.target/addon.node
  COPY Release/addon.node
make: Leaving directory `/home/user1/node-addon-examples/5_function_factory/node_0.12/build'

При выполнении

user1@ubuntu:~/node-addon-examples/5_function_factory/node_0.12$ node addon.js
node: symbol lookup error: /home/user1/node-addon-examples/5_function_factory/node_0.12/build/Release/addon.node: undefined symbol: _Z9bibl_initP4bibl

Отладочная информация:

user1@ubuntu:~/node-addon-examples/5_function_factory/node_0.12$ nm -C build/Release/addon.node | grep bibl_init
                 U bibl_init(bibl*)

person Yawar    schedule 30.07.2015    source источник


Ответы (1)


Проблема заключалась в обмене данными между C++ и C. В приведенном выше случае заголовочный файл C был включен в код C++. Компиляция ожидала код C++. Итак, при компиляции компоновщик задохнулся из-за несоответствия в скомпилированном коде.

Поэтому я использовал директиву extern «C», чтобы сообщить компилятору о файлах заголовков C с помощью следующего кода.

extern "C" {
    #include "bibutils.h"
    #include "bibprogs.h"
}
person Yawar    schedule 04.08.2015