2012-03-28 3 views
11

C 프로그램과 혼합 된 사용자 정의 node.js addon을 작성하고 있습니다.사용자 정의 node.js addon을 빌드 할 수 있지만 포함 할 수 없음

addon.cc 그것은 다른 .CC 파일이 포함

#define BUILDING_NODE_EXTENSION 
#include <node.h> 
#include <node_buffer.h> 

using namespace v8; 
using namespace node; 


/* other logic and function... */ 


Handle<Value> RunCallback(const Arguments& args) { 
    HandleScope scope; 

    Local<Value> buffer1 = args[0]; 
    size_t size = Buffer::Length(buffer1->ToObject()); 
    char* bufferdata = Buffer::Data(buffer1->ToObject()); 

    /* some logic written in C style ... */ 

    Local<Function> cb = Local<Function>::Cast(args[1]); 
    const unsigned argc = 1; 
    Local<Value> argv[argc] = { Local<Value>::New(String::New(outputdata, outputSize)) }; 

    cb->Call(Context::GetCurrent()->Global(), argc, argv); 

    return scope.Close(Undefined()); 
} 

void Init(Handle<Object> target) { 
    target->Set(String::NewSymbol("runCallback"), FunctionTemplate::New(RunCallback)->GetFunction()); 
} 

NODE_MODULE(addon, Init) 

과 같이 구성되어 있으므로 WScript와는은 다음과 같이이다 :

srcdir = '.' 
blddir = 'build' 
VERSION = '0.0.1' 

def set_options(opt): 
    opt.tool_options('compiler_cxx') 

def configure(conf): 
    conf.check_tool('compiler_cxx') 
    conf.check_tool('node_addon') 

def build(bld): 
    obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') 
    obj.target = 'addon' 
    obj.source = ['addon.cc', 'otherFiles.cc'] 

내가 노드 웹 애플리케이션 방화벽 구성을 실행하면, 그것은 보여줍니다 :

Checking for program g++ or c++   : /usr/bin/g++ 
Checking for program cpp     : /usr/bin/cpp 
Checking for program ar     : /usr/bin/ar 
Checking for program ranlib    : /usr/bin/ranlib 
Checking for g++       : ok 
Checking for node path     : not found 
Checking for node prefix     : ok /usr/local 
'configure' finished successfully (0.169s) 

노드 - waf 빌드를 실행하면 다음과 같이 나타납니다 :

Waf: Entering directory `/path/build' 
[ 1/25] cxx: addon.cc -> build/Release/addon_1.o 
... list of file ... 
build/Release/list of file -> build/Release/addon.node 
Waf: Leaving directory `/path/build' 
'build' finished successfully (0.544s) 

하지만 노드 REPL에서 다음을하려고 할 때, 그것은 보여줍니다

var addon = require("./build/Release/addon"); 
Error: Unable to load shared library /path/build/Release/addon.node 
    at Object..node (module.js:472:11) 
    at Module.load (module.js:348:31) 
    at Function._load (module.js:308:12) 
    at Module.require (module.js:354:17) 
    at require (module.js:370:17) 
    at repl:1:13 
    at REPLServer.eval (repl.js:80:21) 
    at repl.js:190:20 
    at REPLServer.eval (repl.js:87:5) 
    at Interface.<anonymous> (repl.js:182:12) 

그것은 매우 이상하다. 내가 파일 시스템 구조와 일치한다는 것을 확인했다 :

$ file build/Release/addon.node 
build/Release/addon.node: Mach-O 64-bit bundle x86_64 

$ file `which node` 
/usr/local/bin/node: Mach-O 64-bit executable x86_64 

을 nm에서 살펴보면, 다음과 같은 보여줍니다

nm ./build/Release/addon.node 
0000000000011880 s GCC_except_table30 
0000000000001160 t _Init 
       U __Unwind_Resume_or_Rethrow 
       U ___bzero 
       U ___gxx_personality_v0 
0000000000013220 D _addon_module 
       U _free 
0000000000013600 D _lsfmeanTbl 
0000000000013420 D _memLfTbl 
       U _memcpy 
       U _memmove 
       U _puts 
       U _realloc 
0000000000011950 s _ssqEn_win.2272 
000000000001341c D _stMemLTbl 
00000000000132e0 D _state_frgqTbl 
00000000000132c0 D _state_sq3Tbl 
       U dyld_stub_binder 
       (... many are omitted ...) 

무엇 가능한 이유가 될 것인가? C 파일을 C++ 파일과 결합하여 컴파일 할 수 없습니까? 모든 malloc/realloc/free를 제거해야합니까? 아니면 다른 이유가 있을까요?

+0

Mac 및 Linux에서 빌드를 시도했지만 결과는 동일하며 라이브러리를 포함 할 때 오류가 표시됩니다. –

+0

나는 문제가 외부 C 파일 때문이라고 확신한다. 하지만 왜? 나는 의심한다. –

+2

아마도 node.js addon을 작성하기위한 순수한 C 솔루션이 있습니까? –

답변

0

Node.js를 사용함으로써 버전> = 0.7.6. 문제가 해결되었습니다. 또한 디버그 메시지가 훨씬 많습니다.

0

랩 초기화의 정의() 및 익스포트 심볼 맹 글링 ++ C 이름을 피하기 extern "C"에서 NODE_MODULE 매크로 :

extern "C" { 

void Init(Handle<Object> target) { 
    target->Set(String::NewSymbol("runCallback"), FunctionTemplate::New(RunCallback)->GetFunction()); 
} 

NODE_MODULE(addon, Init) 
} 
관련 문제