一個快速的谷歌搜索至少可以編寫一個爲node.js編寫C++ "Hello World"的教程,但是目前還不清楚是否可以僅使用C編寫這樣的擴展。假設可能,我面臨什麼挑戰/限制?是否可以在C(而不是C++)中編寫node.js擴展?
回答
如果需要,您可以用C語言編寫擴展的部分代碼,但您至少需要一小部分C++代碼來將C代碼與Node粘合在一起。
正如您將在HelloWorld中看到的那樣,擴展依賴於v8.h
和node.h
標題,其中包含Node所需的所有類。如果沒有這些,您將無法正確創建JS對象以導出回節點。也就是說,你可以非常輕鬆地編寫一小組調用C函數幷包裝某種C結構的C++函數。
發現這個Hacker News上:
https://github.com/wesolows/v8plus
V8 +:節點附加C++到C邊界
這層提供了一種方法用C來寫,至少簡單的節點插件,不用所有可怕的C++ goop,否則你可能會使用它。該goop仍然存在,但你不必寫它。更重要的是,你可以在一個合理的編程環境中編寫你的模塊,避免混淆和容易出錯的C++語義。
看起來像它不會工作的版本> Node.js 0.10,只是提出一個問題,找出肯定 –
需要在使用的extern申報個人的C函數的C++代碼 「C」 語法
例子:
#define BUILDING_NODE_EXTENSION
#include <node.h>
extern "C" void f(int i, char c, float x);
using namespace v8;
如果你有多個C函數,那麼就可以通過分組括號:
extern "C" {
void f(int i, char c, float x);
int g(char* s, char const* s2);
double sqrtOfSumOfSquares(double a, double b);
}
然後從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)
注意:使用示例代碼Nodejs Addons
現在我們至少有3點不錯的選擇:
節點FFI: Node.js的外部函數接口
插件加載並調用動態使用純JavaScript的庫。它可用於而無需編寫任何的C代碼創建綁定本機庫
https://github.com/node-ffi/node-ffi
痛飲:簡單包裹生成
(它會產生許多語言包裝,有什麼解決一次許多問題)
http://www.swig.org/
emscripten
編譯C和C++到運行甚至以接近原生速度的網絡,而無需插件高度優化的JavaScript的。
http://kripken.github.io/emscripten-site/
如果你的模塊使用libuv你可以將其鏈接到該節點的可執行文件。它以共享庫的形式導出libuv函數。
然後你可以使用node-ffi來與它接口(這裏不需要C++知識)。
這是我如何做它在Windows下使用MSVS:
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");
}
使用testlib.def:
EXPORTS set_timer
記住鏈接到node.lib
- 移動創建DLL來測試文件夾並在那裏運行這些命令:
npm install ffi
(目前需要構建工具。檢查指令)
node test-lib.js
測試lib.js是在這裏:
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')
發揮你的想象力。我們在libuv中有網絡,工作線程和其他選項...
- 1. 是否可以用C++而不是C編寫OpenCL內核?
- 2. 能否在Go中寫一個本地Node.js擴展,而不是C++?
- 3. 如何在OSX上爲Python編譯C++擴展(而不是C)?
- 4. 是否可以在C#中編寫DirectShow過濾器(不在c \ C++中)?
- 5. 是否可以在Libgdx中編寫C/C++代碼?
- 6. 是否可以在C#/ LINQ中擴展查詢關鍵字?
- 7. 是否可以在Python C擴展中包含socketmodule.h?
- 8. 是否可以在C#中創建擴展運算符?
- 9. 是否可以在C#中擴展數組?
- 10. 是否可以在Objective-C擴展中定義ivars?
- 11. C#擴展方法,而不是迭代
- 12. 是否可以擴展DefaultValueAccessor?
- 13. 是否可以擴展DataColumn.Expression
- 14. 是否可以從擴展
- 15. 是否可以擴展類
- 16. 是否可以在C++中編寫通用可變參數zipWith?
- 17. 是否可以在Android中擴展Canvas?
- 18. 是否可以爲控制檯編寫擴展方法?
- 19. 是否可以編寫移動Safari擴展?
- 20. 是否可以在PHP中以編程方式啓用擴展?
- 21. 我可以在D中創建一個Python擴展模塊(而不是C)
- 22. 你可以用C#編寫C++包裝,而不是使用C++/CLI嗎?
- 23. 是否可以在C/SDL中編寫Tower Defense
- 24. 在C#中編寫鉻擴展?
- 25. 是否可以使用c#編寫a = b == c?
- 26. C++中是否有擴展套接字?
- 27. ActionScript:Tweener可以向上擴展而不是向下擴展?
- 28. 是否可以在VisualStudio的XSLT編輯器中使用XSLT擴展(sitecore擴展)?
- 29. 是否可以擴展現有的Objective-C塊?
- 30. C++的value_type是否可以從iterator_traits擴展到所有類型?
指向你的C++教程的鏈接將有助於 – lupz
https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native -extensions/ – noahlz