2013-05-28 26 views
16

tôi đã có một số C++ hiện mã mà không xử lý số trong C++ ứng dụng độc lập. Bây giờ tôi muốn sử dụng mã đó trong một ứng dụng node.js mới.nút-ffi vs nút mở rộng để truy cập vào C++ hiện chức năng

nghiên cứu làm thế nào để truy cập vào C++ mã từ Node.js, hai lựa chọn đưa ra:

  1. Viết một phần mở rộng Node.js
  2. Sử dụng node-ffi

nút-ffi có vẻ như một tốt tùy chọn để truy cập các thư viện hiện có, nhưng tôi có nghĩ đúng nếu tôi sử dụng nút-ffi tôi sẽ phải viết trình bao bọc C để làm cho C++ của tôi có thể truy cập được không? (Đây là cách duy nhất tôi có thể nhận được một trường hợp thử nghiệm đơn giản để làm việc trên Windows với Visual Studio).

Đối với trường hợp của tôi, nơi mã nguồn của tôi đã có trong C++, không phải C, các cân nhắc trong việc chọn giữa hai tùy chọn ở trên là gì?

+0

Bạn có sử dụng rất nhiều thừa kế, chức năng ảo và các mẫu trong mã của bạn – aaronman

+0

Không mẫu. Không có chức năng ảo. Một số thừa kế, mặc dù tôi có thể sửa đổi mã để tránh điều này nếu cần thiết. – pancake

+0

Tôi nghĩ rằng sẽ tương đối dễ dàng để viết trình bao bọc hơn – aaronman

Trả lời

19

FFI hoạt động với thư viện C động. Điều này có nghĩa là bạn phải để lộ thư viện động của mình bên ngoài. Trong C++, bạn làm điều này với extern "C", như thế này:

#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 

Điều này sẽ làm ++ chức năng C bạn có sẵn cho C-sự vật, như một phương pháp thư viện năng động.

Đây là cách bạn quấn này trong javascript, sau khi bạn đã biên soạn C++ lib của bạn như libmylibrary.dll/.so:

var ffi = require('ffi'); 

var mylibrary = ffi.Library('libmylibrary', { 
    "foo": [ "int", ["int"] ], 
    "bar": [ "int", [] ] 
}); 

Có rất nhiều mát điều mà bạn có thể làm. Hãy khám phá, here

Nếu đây là thư viện nút, chỉ cần đặt các phương thức của bạn vào mô-đun.exports. Dưới đây là một ví dụ đầy đủ của một bọc của mã ++ C ở trên, với đồng bộ & phương pháp không đồng bộ:

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 
}; 

tôi đã không sử dụng node-ffi-generate, nhưng có vẻ khá mát mẻ để tạo ra những loại giấy gói cho bạn.

Nếu tôi lưu tập tin này như mylibrary.js, tôi có thể sử dụng nó như thế này: "? Là nó tốt hơn"

var mylib = require('./mylibrary.js'); 

var num = mylib.fooSync(1); 

// or 

mylib.foo(1, function(er, num){ 

}); 

Đối với các câu hỏi của Tôi nghĩ vậy, đối với hầu hết mọi thứ. Nếu bạn tạo các phương thức bên ngoài C, chúng sẽ hoạt động chỉ bằng mọi ngôn ngữ khác, một số trong đó cũng có FFI, vì vậy bạn sẽ viết tương đương đơn giản ở trên với bất kỳ ngôn ngữ đích nào của bạn. Điều này có nghĩa là rất ít mã để duy trì, khác với cơ bản "tải C + + lib", và "lộn xộn xung quanh với chữ ký của nó để cảm thấy đúng cho ngôn ngữ X". Nó không cụ thể cho nút. Một phần thưởng khác dành cho các thư viện chia sẻ chung (như sqlite, được đưa ra trong ví dụ hướng dẫn.) Bạn có thể không quan tâm chính xác phiên bản của chúng, hoặc muốn bọc nó với mã C++, cần được biên dịch để sử dụng nó. Sử dụng FFI, bạn có thể bọc một lib được biên dịch trước/cài đặt chỉ bằng javascript.

+0

Câu trả lời chi tiết tuyệt vời, cảm ơn rất nhiều! Đó là một thời gian kể từ khi tôi đã viết câu hỏi, và tôi sẽ đồng ý rằng tôi nghĩ rằng bằng cách sử dụng các tuyến đường FFI có lẽ là đơn giản hơn viết một phần mở rộng. node-ffi-generate trông thú vị. – pancake

Các vấn đề liên quan