7

I am new to Javascript and V8 library. My requirement is call a C++ function and return a C struct back to Javascript module.

struct empDetails {
    int empNo;
    string empName;
};

v8::Handle<v8::Value> getDetails(const v8::Arguments &args) {
    if ((args.Length() != 1) || !args[0]->IsUint32()) {
        return v8::ThrowException(v8::Exception::Error    
                (v8::String::New("Invalid> arguments.")));
    }
    uint32_t userId = args[0]->ToUint32()->Value();
    empDetails e;
    company::GetEmpdetails(userId, e); // other static function in my project
    return e;
}

At return statement, I am getting error. Could anyone tell me how to return a struct from V8 C++ function.

3
  • 2
    What does it mean to return a C struct to JavaScript? Wouldn't you want (need?) to wrap it in a JavaScript Object like {empNo:1,empName:"John Doe"}? Commented Nov 1, 2012 at 16:12
  • 1
    The V8 embedder's guide section about Object Templates will likely get you on the right track. Commented Nov 1, 2012 at 16:26
  • seems to be I have not read enough about v8 object templates, thanks for your reply Commented Nov 1, 2012 at 17:50

3 Answers 3

6

You want to create Javascript object and populate every member of it with your data.

#define function(name) v8::Handle<v8::Value> name(const v8::Arguments& a)

    function (example_object) {
        v8::HandleScope handle_scope;
        Handle<Object> Result = Object::New();
        Result->Set(String::New("name"), String::New("Stackoverflow"));
        Result->Set(String::New("url"), String::New("http://stackoverflow.com"));
        Result->Set(String::New("javascript_tagged"), Number::New(317566));
        return handle_scope.Close(Result);
    }

Call from Javascript:

log(JSON.stringify(example_object()))

Output

{"name":"Stackoverflow","url":"http://stackoverflow.com","javascript_tagged":317566}
Sign up to request clarification or add additional context in comments.

Comments

1

When you want to create node.js module,

npm install ref
npm install ref-array
npm install ref-struct

in your js source:

var ref = require('ref');
var ArrayType = require('ref-array')
var StructType = require('ref-struct');
var empDetails = StructType({
    empNo: ref.types.int,
    empName: ArrayType('char', STRING_LENGTH)
});
var result = new empDetails;
getDetails(999, result.ref());

in your module source:

struct empDetails {
    int empNo;
    char empName[STRING_LENGTH];
};
v8::Handle<v8::Value> getDetails(const v8::Arguments &args) {
    if((args.Length() != 2) || !args[0]->IsUint32()){
        return v8::ThrowException(v8::Exception::Error    
            (v8::String::New("Invalid> arguments.")));
    }
    uint32_t userId = args[0]->ToUint32()->Value();
    struct empDetails src;
    company::GetEmpdetails(userId, src);
    v8::Handle<v8::Object> dst = args[1]->ToObject();
    if(node::Buffer::Length(dst) >= sizeof(struct empDetails))
        memcpy(node::Buffer::Data(dst), &src, sizeof(struct empDetails));
    return args.This();
}

Comments

0

C++

struct empDetails {
    int empNo;
    string empName;
};

void getDetails(const FunctionCallbackInfo<Value>& args) {

    Isolate* isolate = args.GetIsolate();
    HandleScope scope(isolate);

    if(args.Length() != 1) {
        isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")));
        return;
    } 

    if (!args[0]->IsNumber()) { 
        isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments")));
        return;
    }

    int empId = args[0]->NumberValue();

    // You can call your c++ function here instead of a returning a dummy struct
    empDetails e;
    e.empNo = empId;
    e.empName "Hello World";

    Local<Object> result = Object::New(isolate);
    result->Set(String::NewFromUtf8(isolate, "empNo"), Number::New(isolate, e.empNo));
    result->Set(String::NewFromUtf8(isolate, "empName"), String::NewFromUtf8(isolate, e.empName.c_str()));

    args.GetReturnValue().Set(result);        

}

Javascript

const emp = require('your-module')
var empDetails = obj.getDetails(123)
console.log("number:" + empDetails.empNo + " name: " + empDetails.empNo) 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.