2012-05-06 32 views
17

Tìm kiếm nhanh trên google có ít nhất một hướng dẫn để viết C++ "Hello World" cho node.js, nhưng không rõ liệu có thể viết phần mở rộng như vậy chỉ bằng C. Giả sử có thể có những thách thức/giới hạn nào?Có thể viết phần mở rộng node.js trong C (không phải C++) không?

+2

Liên kết tới hướng dẫn C++ của bạn sẽ giúp – lupz

+0

https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native -extensions/ – noahlz

Trả lời

15

Bạn có thể viết các phần của phần mở rộng của bạn trong C nếu bạn muốn, nhưng bạn sẽ cần ít nhất một chút mã C++ để dán mã C với Node của bạn.

Như bạn sẽ thấy trong HelloWorld, các tiện ích dựa trên các tiêu đề v8.hnode.h, có tất cả các lớp mà Node mong đợi. Nếu không có những thứ đó, bạn sẽ không thể tạo đúng đối tượng JS để xuất trở lại Node.

Điều đó nói rằng, bạn có thể khá dễ dàng chỉ cần viết một tập nhỏ các hàm C++ mà chỉ cần gọi hàm C và bọc một số cấu trúc C.

2

Mã tương tác trực tiếp với node.js cần phải được viết bằng C++.

Bạn thể viết extern "C" wrappers sử dụng các loại đục cho tất cả mọi thứ bạn cần từ node.hv8.h, nhưng đây có thể dễ dàng hơn để chỉ cần sử dụng C++ để thay thế (trong đó, tất nhiên, có thể gọi ra để mã C).

8

Các mặt hàng này trên Hacker Tin tức:

https://github.com/wesolows/v8plus

v8 +: Node addon C++ C ranh giới

Lớp này cung cấp một cách để viết ít nhất đơn giản addons Node trong C mà không cần tất cả các khủng khiếp C++ goop nếu không bạn sẽ được dự kiến ​​sẽ sử dụng. Goop đó vẫn tồn tại, nhưng bạn không phải viết nó. Quan trọng hơn, bạn có thể viết mô-đun của bạn trong một môi trường lập trình lành mạnh, tránh các ngữ nghĩa C++ khó hiểu và dễ gây nhầm lẫn.

+0

có vẻ như nó sẽ không hoạt động đối với các phiên bản> Node.js 0.10, chỉ cần gửi một vấn đề để tìm hiểu chắc chắn –

5

Cần khai báo hàm C cá nhân trong C++ mã sử dụng extern "C" cú pháp

Ví dụ:

#define BUILDING_NODE_EXTENSION 
#include <node.h> 

extern "C" void f(int i, char c, float x); 

using namespace v8; 

nếu bạn có nhiều chức năng C, sau đó nó có thể được nhóm qua niềng răng:

extern "C" { 
    void f(int i, char c, float x); 
    int g(char* s, char const* s2); 
    double sqrtOfSumOfSquares(double a, double b); 
} 

rồi gọi hàm từ hàm C++:

Handle<Value> MyFunction(const Arguments& args) { 
    HandleScope scope; 
    f(7, 'x', 3.14); // <--- 
    return scope.Close(String::New("Hello")); 
} 

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

    Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction); 
    Local<Function> fn = tpl->GetFunction(); 
    fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous 

    return scope.Close(fn); 
} 

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


NODE_MODULE(addon, Init) 

Lưu ý: Sử dụng mẫu mã từ Nodejs Addons

5

Bây giờ chúng ta có ít nhất 3 lựa chọn tốt:

nút-ffi: Giao diện chức năng Node.js Ngoại
addon cho tải và kêu gọi động thư viện sử dụng JavaScript thuần túy.Nó có thể được sử dụng để tạo ra các ràng buộc để các thư viện nguồn gốc mà không cần viết bất kỳ mã C
https://github.com/node-ffi/node-ffi

SWIG: Giản Wrapper và Interface Generator
(nó tạo giấy gói cho nhiều ngôn ngữ, những gì giải quyết được nhiều vấn đề cùng một lúc)
http://www.swig.org/

emscripten
Biên dịch C và C++ vào hoạt Javascript cao optimizable chạy ngay cả trên các trang web với tốc độ gần như nguyên bản, mà không cần plug-in.
http://kripken.github.io/emscripten-site/

0

Nếu mô-đun của bạn sử dụng libuv bạn có thể liên kết nó với nút thực thi. Nó xuất khẩu các chức năng libuv như một thư viện được chia sẻ.

Sau đó, bạn có thể sử dụng nút-ffi để giao tiếp với nó (không cần kiến ​​thức C++ ở đây).

Dưới đây là cách tôi đã làm cho nó trên Windows, sử dụng MSVS:

  • Tạo một giải pháp DLL mới trong MSVS
  • Tải libuv và sao chép bao gồm và các file lib vào MSVS
  • Tải về các tập tin node.lib và đặt nó trong thư mục lib của MSVS
  • Biên dịch nguồn ví dụ bên dưới để thêm bộ hẹn giờ vào vòng lặp sự kiện chính

testlib.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "uv.h" 

void (*p_callback)(int number, char *text); 

void timer_cb1 (uv_timer_t* timer, int status) { 
    printf("libuv timer here\n", status); 
    p_callback(123, "it worked!"); 
} 

void set_timer (int interval, void *pfunction) { 
    uv_loop_t *loop; 
    uv_timer_t *timer1; 

    printf("set_timer called. interval=%d callback=%p\n", interval, pfunction); 

    p_callback = pfunction; 

    printf("uv_version_string = %s\n", uv_version_string()); 

    loop = uv_default_loop(); 
    if (loop == 0) { 
    puts("could not get the reference to the default loop"); 
    return; 
    } 

    puts("got the default loop. now allocating the timer struct"); 

    timer1 = (uv_timer_t *) malloc(sizeof(uv_timer_t)); 
    if (timer1 == 0) { 
    puts("malloc failed"); 
    return; 
    } 

    puts("initializing timer"); 
    uv_timer_init(loop, timer1); 

    puts("starting timer"); 
    uv_timer_start(timer1, (uv_timer_cb) &timer_cb1, interval, interval); 

    puts("timer created. returning"); 

} 

sử dụng testlib.def:

EXPORTS set_timer 

Và hãy nhớ để liên kết đến node.lib

  • Di chuyển dll tạo vào thư mục kiểm tra và chạy các lệnh này tại đó:

npm install ffi (hiện tại công cụ xây dựng là bắt buộc. kiểm tra hướng dẫn)

node test-lib.js

thử lib.js là ở đây:

var ffi = require('ffi'); 

var testlib = ffi.Library('testlib', { 
    'set_timer': [ 'void', [ 'int', 'pointer' ] ] 
}); 

var callback = ffi.Callback('void', ['int', 'string'], 
    function(number, text) { 
    console.log("javascript callback here!!! number=" + number + " text=" + text); 
    } 
); 

console.log('registering the callback...'); 
testlib.set_timer(500, callback); 
console.log('done') 

Sử dụng trí tưởng tượng của bạn. Chúng tôi có mạng, chủ đề công nhân và các tùy chọn khác bên trong libuv ...

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