首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用从node.js外接程序构建的模块中的C++

问如何使用从node.js外接程序构建的模块中的C++
EN

Stack Overflow用户
提问于 2015-11-05 10:20:58
回答 1查看 2K关注 0票数 8

我需要使用node.js内置模块‘密码’从我的C++插件。我试图找到使用内置模块但失败的C++加载项的示例。我查看了node_cryp.h/..cc,它具有与node.js密码文档、受保护的构造函数等非常不同的函数签名。node_crypto.h包含带有一个参数的InitCrypto()声明,但node_crypto.cc没有定义此类函数。只有四个参数的InitCrypto。无论如何,我尝试用一个参数使用InitCrypto,得到了“符号查找错误”。

我可以将require('crypto')的结果传递给我的addon,然后使用这个对象,但是这是不安全的。我们的JS代码在客户端的服务器上工作。

现在,我认为对于C++插件来说,使用smth类似openssl而不是内置在节点模块“crypto”中更简单。

因此,我需要一些C++的工作示例,它使用'crypto‘模块,或者链接到有关这方面的文章。

任何使用C++插件内置模块的示例都会有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-06 07:10:05

当需要在Nodejs附件中对数据进行加密/解密时,我使用了同样的方式。

据我所知,来自node_crypto.h的类用于在Nodejs中生成本机绑定,我不能在我的插件中使用它们。

然后,我尝试使用Nodejs中的OpenSSL,但没有做到,因为OpenSSL是静态链接到Nodejs可执行文件的。

之后,我尝试从JavaScript调用C++代码,最后得到了以下解决方案--从C++代码调用Nodejs函数:

代码语言:javascript
复制
using namespace v8;

// persistent handle for the crypto module
static Persistent<Object> node_crypto;

// Addon startup procedure
void Init(Local<Object> exports, Local<Object> module)
{
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    // get `require` function
    Local<Function> require = module->Get(String::NewFromUtf8(isolate, "require")).As<Function>();

    // call require('crypto')
    Local<Value> args[] = { String::NewFromUtf8(isolate, "crypto") };
    Local<Object> crypto = require->Call(module, 1, args).As<Object>();

    // store crypto module in persistent handle for further use
    node_crypto.Reset(isolate, crypto);   
}

NODE_MODULE(addon, Init);

// must be invoked in then Node main thread since the function uses V8 API
std::string encrypt(std::string const& key, std::string const& text)
{
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    // get local handle from persistent
    Local<Object> crypto = Local<Object>::New(isolate, node_crypto);

    // get `createCipher` function from the crypto module
    Local<Function> createCipher = crypto->Get(String::NewFromUtf8(isolate, "createCipher")).As<Function>();

    // call crypto.createCipher("aes256", key)
    Local<Value> create_args[] =
    {
        String::NewFromUtf8(isolate, "aes256"),
        String::NewFromUtf8(isolate, key.c_str())
    };
    Local<Object> cipher = createCipher->Call(crypto, 2, create_args).As<Object>();

    // get update and final functions from the crypto module
    Local<Function> update = cipher->Get(String::NewFromUtf8(isolate, "update")).As<Function>();
    Local<Function> final = cipher->Get(String::NewFromUtf8(isolate, "final")).As<Function>();

    // buf1 = cipher.update(text), buf2 = cipher.final()
    Local<Value> update_args[] = { node::Buffer::New(isolate, text.data(), text.size()) };

    Local<Value> buf1 = update->Call(cipher, 1, update_args);
    Local<Value> buf2 = final->Call(cipher, 0, nullptr);

    // concatenate update and final buffers into result string
    char const* const data1 = node::Buffer::Data(buf1);
    char const* const data2 = node::Buffer::Data(buf2);

    size_t const size1 = node::Buffer::Length(buf1);
    size_t const size2 = node::Buffer::Lenght(buf2);

    std::string result;
    result.reserve(size1 + size2);
    result.append(data1, size1);
    result.append(data2, size2);
    return result;
}

std::string decrypt(std::string const& key, std::string const& text)
{
    // similar as in encrypt, use createDecipher instead
}

正如您所看到的,使用C++ API的V8代码非常冗长。在实际项目中,我使用v8pp库中的实用程序函数获取对象属性,并调用函数,并将数据转换为V8句柄。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33542023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档