2015-07-21 35 views
0

我正在嘗試爲NodeJS C++ Addon使用V8::AddMemoryAllocationCallback方法。我想調用該方法並返回該大小值。我想出了以下代碼。似乎不是調用回調方法。 代碼取自goingnative npm模塊。如何在C++ NodeJS插件中使用V8 :: AddMemoryAllocationCallback方法

memCallback方法沒有得到觸發器。爲什麼?如何解決它?

它將使用以下C++代碼來訪問V8庫。

//myaddon.cc 
#include <nan.h> 
# include <unistd.h> 
#include <iostream> 
#include <fstream> 

using namespace std; 
using namespace v8; 

static int x = 0; 
static int y = 0; 

void memCallback(ObjectSpace space, AllocationAction action, int size) { 
    ofstream myfile; 
    myfile.open ("/tmp/example.txt"); 
    myfile << "Writing this to a file.\n"; 
    myfile.close(); 

    x = size; 
} 

NAN_METHOD(Delay) { 
    NanScope(); 

    int delay = args[0].As<Number>()->IntegerValue(); 
    Local<Function> callback = args[1].As<Function>(); 

    V8::AddMemoryAllocationCallback(&memCallback, kObjectSpaceNewSpace, kAllocationActionAllocate); 

    for(int i = 0; i < 10; i++) { 
    y = i; 
    Local<Value> argv[] = {NanNew(x), NanNew(y)}; 
    NanMakeCallback(NanGetCurrentContext()->Global(), callback, 2, argv); 
    usleep(delay * 1000); 
    } 

    NanReturnUndefined(); 
} 

void Init(Handle<Object> exports) { 
    exports->Set(NanNew("delay"), NanNew<FunctionTemplate>(Delay)->GetFunction()); 
} 

NODE_MODULE(myaddon, Init) 

節點GYP具有用於構建和運行的代碼(嘗試node-gyp rebuild && node index.js 1000 && ls /tmp/從當前文件夾)

//binding.gyp 
{ 
    "targets": [ 
    { 
     "target_name": "myaddon", 
     "sources": [ "myaddon.cc" ], 
     "include_dirs": [ "<!(node -e \"require('nan')\")" ] 
    } 
    ] 
} 

以下是JavaScript代碼。我創建了一些變量來分配內存。

//index.js 
var addon = require('bindings')('myaddon') 

addon.delay(process.argv[2], function(x, y) { 
    console.log("X: ", x, " Y:", y); 

    var arr = [], obj = {}; 
    for (var i = 0; i < 100; i++) { 
     arr.push("Text " + i); 
    } 
    for (var i = 0; i < 100; i++) { 
     obj[i] = arr[i]; 
     delete arr[i]; 
    } 
    console.log('Done!'); 
}) 

console.log("The End"); 

電流輸出是;

X: 0 Y: 0 
Done! 
X: 0 Y: 1 
Done! 
X: 0 Y: 2 
Done! 
X: 0 Y: 3 
Done! 
X: 0 Y: 4 
Done! 
X: 0 Y: 5 
Done! 
X: 0 Y: 6 
Done! 
X: 0 Y: 7 
Done! 
X: 0 Y: 8 
Done! 
X: 0 Y: 9 
Done! 
The End 
+0

'AddMemoryAllocationCallback()'回調可能會在主線程中調用,所以目前您通過在for循環中休眠來阻止該線程。如果你刪除了循環,你會看到正在寫入的'example.txt'嗎? – mscdex

+0

@mscdex我刪除了'for loop'和'usleep'。但是我看不到'example.txt'。你是否認爲我的代碼編寫得很好(任何語法錯誤)?我不確定'V8 :: AddMemoryAllocationCallback(&memCallback,kObjectSpaceNewSpace,kAllocationActionAllocate);''或'V8 :: AddMemoryAllocationCallback(memCallback,kObjectSpaceNewSpace,kAllocationActionAllocate);'。如何添加函數引用? – gihanchanuka

+1

您是否嘗試過其他參數,如'kObjectSpaceAll'而不是'kObjectSpaceNewSpace'和/或'kAllocationActionAll'而不是'kAllocationActionAllocate'? – mscdex

回答

2

使用更少的限制通知的設置可有助於(kObjectSpaceAll代替kObjectSpaceNewSpace和/或kAllocationActionAll代替kAllocationActionAllocate)。

對於傳遞size到您的回調,這裏有幾種方法去做:

  • 首先,你可能會考慮使用EventEmitter代替回調以來memCallback將被調用很多次,除非你真的只需要回調爲下一個memCallback調用啓動。使用EventEmitter解決方案,您只需在C++ land中註冊一次JS回調,該回調將全局存儲並在memCallback內部調用。然後在JS領域,當你的JS回調被執行時,你會發出一個事件。

    你甚至可以調整,以便JS回調(甚至C + +回調)只保留在C++陸地註冊,如果有事件的偵聽器(EventEmitter提供事件通知你,當偵聽器添加和刪除事件)。這可能有助於提高性能。

  • 如果您真的想要使用多次執行的回調(這實際上違背了節點社區的一般預期),那麼您將不得不將JS回調存儲在某種全局C++數組結構中提供了一些方法來「註銷」JS回調,所以他們不會再被調用(將從C++數組中刪除JS回調)。

+0

我同意你的建議。所以,你建議像https://github.com/bnoordhuis/node-event-emitter這樣的東西(如果它是一個NAN例子,那將會很棒)。但我不明白爲什麼'x'值沒有改變。我有什麼問題嗎?如何解決它? – gihanchanuka

+0

我需要將這些值('size')每100ms發送給JS並重置它。即使通過'memCallback'會以較小的間隔調用,我想確保這些細節每隔100ms進入JS。 – gihanchanuka

相關問題