2013-05-28 6 views
16

독립형 C++ 응용 프로그램에서 수치 처리를 수행하는 기존 C++ 코드가 있습니다. 이제 새로운 node.js 응용 프로그램 내에서 해당 코드를 사용하려고합니다. Node.js를에서 ++ 코드를 C에 액세스하는 방법을 검토 한 결과node-ffi 대 기존 C++ 기능에 액세스하기위한 노드 확장

, 두 가지 옵션이 올 :

  1. node-ffi

노드 FFI 좋은처럼 보이는 Node.js를 확장

  • 사용 쓰기 옵션을 사용하여 기존 라이브러리에 액세스 할 수 있지만 node-ffi를 사용할 경우 C++ 래퍼를 작성하여 액세스 할 수 있어야합니다. (이것은 Visual Studio로 Windows에서 작동하는 간단한 테스트 케이스를 얻을 수있는 유일한 방법이었습니다).

    내 소스 코드가 이미 C가 아닌 C++에있는 경우 위의 두 옵션 중에서 선택할 때 고려해야 할 사항은 무엇입니까?

  • +0

    코드에 상속, 가상 함수 및 템플릿을 많이 사용합니까? – aaronman

    +0

    템플릿이 없습니다. 가상 기능이 없습니다. 어떤 상속, 비록 내가 필요하다면 이것을 피하기 위해 코드를 수정할 수는 있지만. – pancake

    +0

    나는 래퍼를 쓰는 것이 상대적으로 쉽다고 생각한다. – aaronman

    답변

    19

    FFI는 동적 C 라이브러리와 함께 작동합니다. 즉 동적 라이브러리를 외부에 노출해야합니다. C++에서는 다음과 같이 통근자 "C"이 작업을 수행 :

    #ifdef __cplusplus 
    extern "C" { 
    #endif 
    
    int foo (int param){ 
        int ret = 0; 
        // do C++ things 
        return ret; 
    } 
    
    int bar(){ 
        int ret = 0; 
        // do C++ things 
        return ret; 
    } 
    
    #ifdef __cplusplus 
    } 
    #endif 
    

    은 동적 라이브러리 방법으로, C-가지로 C++ 기능을 사용할 수있게됩니다. 여기

    는로 C++ lib 디렉토리를 컴파일 한 후, 자바 스크립트에서이 포장 방법입니다 libmylibrary.dll/.so를 :

    쿨러를 많이 당신이 할 수있는 일이있다
    var ffi = require('ffi'); 
    
    var mylibrary = ffi.Library('libmylibrary', { 
        "foo": [ "int", ["int"] ], 
        "bar": [ "int", [] ] 
    }); 
    

    . 확인해보십시오. here

    노드 라이브러리 인 경우 모듈을 module.exports에 넣기 만하면됩니다. 내가 node-ffi-generate을 사용하지 않은

    var ffi = require('ffi'); 
    
    var mylibrary = ffi.Library('libmylibrary', { 
        "foo": [ "int", ["int"] ], 
        "bar": [ "int", [] ] 
    }); 
    
    module.exports = { 
        fooSync : mylibrary.foo, 
        foo: mylibrary.foo.async, 
        barSync : mylibrary.bar, 
        bar: mylibrary.bar.async 
    }; 
    

    ,하지만 당신에 대한 래퍼의 이러한 종류를 생성하는 정말 멋진 외모 : 여기에 동기 & 비동기 방법으로, 위의 C++ 코드의 랩의 전체 예입니다. 나는이처럼 사용할 수

    내가 mylibrary.js으로이 파일을 저장 한 경우 : "그것이 더"의 문제에 관해서는

    var mylib = require('./mylibrary.js'); 
    
    var num = mylib.fooSync(1); 
    
    // or 
    
    mylib.foo(1, function(er, num){ 
    
    }); 
    

    나는 대부분의 것들을 그렇게 생각한다. 당신이 당신의 방법 C를 extern C로 만들면, 그들은 다른 모든 언어에서도 작동 할 것입니다. 그 중 일부는 FFI를 가지고 있기 때문에, 당신은 당신의 목표 언어가 무엇이든 위의 간단한 것에 상응하는 것을 쓸 것입니다. 이는 기본 "load C++ lib"이외의 유지 관리 할 코드가 거의없고 "언어 X에 대해 올바르게 느끼기위한 서명이 엉망입니다"라는 의미입니다. 노드와 관련이 없습니다. 또 다른 보너스는 일반적인 공유 라이브러리 (자습서 예제에서 제공 한 sqlite와 같은)입니다. 여러분이 사용하는 버전이 무엇인지 정확하게 신경 쓰지 않거나 더 많은 C++ 코드로 감싸고 싶다면 사용하기 위해 컴파일해야합니다. FFI를 사용하면 미리 컴파일 된/설치된 lib를 자바 스크립트로 감쌀 수 있습니다.

    +0

    훌륭한 상세 답변, 고마워요! 제가 질문을 쓴 이래로 얼마 지나지 않아 FFI 경로를 사용하는 것이 아마도 확장 기능을 작성하는 것보다 더 쉽다고 생각합니다. node-ffi-generate가 흥미로운 것처럼 보입니다. – pancake