2012-04-26 35 views
10

Gặp tôi khi tôi giải thích điều này.Làm cách nào để truyền một đối tượng C++ được bao bọc tới một cuộc gọi lại Javascript?

Tôi đang cố gắng viết mô-đun Node.js, sử dụng C++, kết thúc tốt đẹp và hiển thị một số lớp từ libhdf5.

Tôi hiện đang quan tâm đến hai lớp học từ libhdf5. Đầu tiên là File và mở tệp hdf5. Cái thứ hai là Group và nó đại diện cho các nhóm trong tệp đó. Bạn nhận được các đối tượng Group từ một đối tượng File.

Tôi đã viết một số mã mà tôi tạo đối tượng File và cố gắng lấy một số Group từ đó. Tôi đang cố gắng làm cho mô-đun Node.js của tôi thành Javascripty càng tốt, vì vậy tôi muốn trả về nhóm bằng cách sử dụng một cuộc gọi lại. Vì vậy, tôi đang cố gắng để mã mô-đun của tôi vì vậy mà nó được sử dụng như thế này:

var hdf5 = require('hdf5'); 
var file = new hdf5.File('/tmp/example.h5'); 
file.getGroup('foobar', function (err, group) { console.log(group); }); 

Vì vậy, trong ++ mã C cho File wrapper của tôi, tôi muốn có một chức năng mà các bản đồ đến getGroup chức năng ở đây, và nó 'd gọi hàm ẩn danh đã cho, chuyển bất kỳ lỗi nào cũng như trình bao bọc đối tượng Group mới.

Vì điều này nghe giống với tài liệu Node.js hiển thị là factory of wrapped objects, tôi đã lập mô hình mã số Group sau các ví dụ ở đó.

Vì vậy, tôi đã mã hóa Group trình bao bọc của mình, nhưng tôi đang cố gắng thực hiện nó. Tôi chưa biết đủ để biết cách bỏ đi bằng cách sử dụng lớp v8 Arguments cho các tham số chức năng. Bởi vì điều đó, tôi dường như không thể vượt qua một số tham số mà tôi cần cho hàm dựng hàm liên tục v8 của tôi (vì tôi đang khởi tạo nó từ C++, chứ không phải từ JS-land).

Ai đó vui lòng xem my code for libhdf5 và cho tôi một con trỏ để biết cách đạt được điều này? Tôi cảm thấy như tôi gần như ở đó, nhưng tôi chỉ thiếu một cái gì đó.

Đây là Group wrapper của tôi, có chức năng xây dựng nhấn mạnh: https://github.com/ryancole/node-hdf5/blob/master/src/h5_group.cc#L57-72

Đây là File wrapper của tôi, với dòng hightlighted nơi tôi sẽ cần phải vượt qua trong các thông số của tôi, như Arguments (hoặc bất cứ điều gì mà tôi cần phải thay đổi điều này để cho tiện làm việc: https://github.com/ryancole/node-hdf5/blob/master/src/h5_file.cc#L110

Cảm ơn trước, và cảm ơn vì đọc bức tường này của văn bản :)

Trả lời

9

Bạn đang ở gần đó.. Bạn không cần phải vượt qua Arguments đến Group::Instantiate. Chỉ cần chuyển những gì bạn cần và sử dụng hàm tạo để tạo phiên bản mới của Group. Ví dụ:

Handle<Value> Group::Instantiate(const std::string& name) { 
    HandleScope scope; 

    Local<v8::Value> argv[1] = { 
     Local<v8::Value>::New(String::New(name.c_str())) 
    }; 

    return scope.Close(Constructor->NewInstance(1, argv)); 
} 

Phương thức Group::New làm phần còn lại của công trình xây dựng.

Handle<Value> Group::New(const Arguments& args) { 
    HandleScope scope; 

    if (!args[0]->IsString()) { 
     return ThrowException(Exception::TypeError(String::New("First argument must be a string"))); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Group * const group = new Group(name); 
    bar->Wrap(args.This()); 

    return args.This(); 
} 

Trong File::OpenGroup bạn có thể làm điều này:

Handle<Value> File::OpenGroup (const Arguments& args) { 
    HandleScope scope; 

    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsFunction()) { 
     ThrowException(Exception::SyntaxError(String::New("expected name, callback"))); 
     return scope.Close(Undefined()); 
    } 
    const std::string name(*(String::Utf8Value(args[0]->ToString()))); 
    Local<Function> callback = Local<Function>::Cast(args[1]); 

    const unsigned argc = 2; 
    Local<Value> argv[argc] = { 
     Local<Value>::New(Null()), 
     Local<Value>::New(Group::Instantiate(name)) 
    }; 
    callback->Call(Context::GetCurrent()->Global(), argc, argv); 

    return scope.Close(Undefined()); 
} 

HTH

+0

Đó là để nói rằng bạn cần một phương pháp nhà máy ('Nhóm :: Instantiate') để trở về một thể hiện của một lớp khác ? – ZachB

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