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?
Trả lời
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.h
và node.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.
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.
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 –
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
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/
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 ...
- 1. không thể tạo phần mở rộng ruby C++
- 2. Có thể mở rộng mảng trong C# không?
- 3. Tôi có thể mở rộng lisp bằng C++ không?
- 4. trong phần mở rộng Python C
- 5. Tại sao Node.js có thể mở rộng?
- 6. Mũi có phải là phần mở rộng của unittest không?
- 7. Có phải C + + CLI là phần phụ của C++ không?
- 8. Làm cách nào để viết phần mở rộng vỏ trong C++?
- 9. Có phải `mở rộng` nhanh hơn` + = `không?
- 10. Tôi có thể 'mở rộng' một cấu trúc trong C?
- 11. Trong C hoặc C++, có cách nào để mở rộng một lớp không thừa kế không?
- 12. Có phải nginx/node.js/postgres là một kiến trúc có khả năng mở rộng không?
- 13. jRuby, đá quý có phần mở rộng C
- 14. PHP không thấy phần mở rộng mysql
- 15. Prototype có thể mở rộng các phần tử SVG không?
- 16. Python nhận SIGSEGV khi tải C++ viết module mở rộng
- 17. Không thể xây dựng phần mở rộng gốc đá quý
- 18. Có thể mở rộng Java Enums không?
- 19. Mở rộng Enum trong C#
- 20. Bạn có thể chuyển mảng 'mở rộng' sang một hàm trong C# như trong ruby không?
- 21. cách tạo phần mở rộng tệp tùy chỉnh trong C#?
- 22. Làm thế nào tôi có thể bọc một lớp C++ trong phần mở rộng php?
- 23. Tôi có thể mở rộng Corona bằng mã gốc không?
- 24. Phương thức mở rộng F # trong C#
- 25. Mở rộng Python bằng C/C++
- 26. Đồng thời: Các phần mở rộng của Python được viết bằng C/C++ có bị ảnh hưởng bởi Khóa thông dịch toàn cầu không?
- 27. Luồng HTTP không có phần mở rộng trong MPMoviePlayerController
- 28. Mở rộng enums trong C++?
- 29. DataRow constructor không thể truy cập được khi viết phần mở rộng DataSet?
- 30. Tôi có thể sử dụng các tính năng C++ trong khi mở rộng Python không?
Liên kết tới hướng dẫn C++ của bạn sẽ giúp – lupz
https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native -extensions/ – noahlz