gpt4 book ai didi

javascript - 如何使用 JavaScriptCore 将 C++ 对象传递给 JavaScript 函数

转载 作者:行者123 更新时间:2023-12-02 10:38:37 25 4
gpt4 key购买 nike

我在外部 JavaScript 文件 sample.js 中用 JavaScript 编写了一个函数。

function fileInfo(obj)
{
/////
}

我在 sample.cpp 文件中定义了一个类,如下所示:
class sample
{
int i;
///
};

///

int main()
{
sample obj;
///
///
}

我们如何将 obj 作为参数传递给 JavaScript 函数“fileInfo”?

最佳答案

您不能将用一种编程语言编码的对象直接传递给用另一种编程语言编写的另一个程序。这是不可能的,因为对象的二进制布局因一种编程语言而异。例如,在 JavaScript 中,数字类型是 64 位浮点数(8 字节)。如果您的 C++ 对象使用 int32(4 个字节),则两个对象在内存中的布局不同。两个对象至少应该具有相同的大小(8 字节)才能兼容(实际上它比这要复杂得多)。总之,为了在不同的编程语言之间交换值,您需要以中性格式达成一致或在数据类型之间进行转换。

用于 C/CCP/Objective-C 等的 FFI(外部函数接口(interface))JavaScript 库允许您保持 C 和 JavaScript 程序之间的 ABI 兼容性。如果您需要混合 C/CPP 和 JavaScript 代码,您可以使用 javascriptcoregtk图书馆。

回到你的例子,你需要转换你的 Sample CPP 反对 JSCValue对象使其工作。由于我在第一段中评论过的原因,强制转换是不够的(程序员需要决定 CPP 对象与其在 JavaScript 中的等效对象之间的转换应该是什么样子)。这是一个可能的解决方案:

/**
* Pass CPP object to JavaScript function
*
* sample.js:
* function fileInfo(obj)
* {
* return "fileInfo: " + obj.i;
* }
*
* To compile: g++ main.cc -o main `pkg-config --cflags --libs javascriptcoregtk-4.0`
*
*/

#include <iostream>
#include <string>
#include <fstream>
#include <streambuf>

#include <jsc/jsc.h>

using namespace std;

class Sample {
public:
Sample(int i) { this->i = i; };
JSCValue* toJSObject(JSCContext* jsContext);
int i;
};

JSCValue* Sample::toJSObject(JSCContext* jsContext)
{
JSCValue* ret = jsc_value_new_object(jsContext, nullptr, nullptr);

JSCValue* i = jsc_value_new_number(jsContext, this->i);
jsc_value_object_define_property_data(ret, "i", JSC_VALUE_PROPERTY_ENUMERABLE, i);

return ret;
}

int main(int argc, char* argv[])
{
// Create jsContext.
JSCContext* jsContext = jsc_context_new();

// Load JavaScript file.
const std::string filename = {"sample.js"};
ifstream t("sample.js");
string code((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
JSCValue* ret = jsc_context_evaluate(jsContext, code.c_str(), static_cast<gssize>(code.length()));

// Query 'fileInfo' and store it into JSCValue.
JSCValue* fileInfo = jsc_context_evaluate(jsContext, "fileInfo", 8);
if (!jsc_value_is_function(fileInfo)) {
cerr << "Couldn't find function 'fileInfo'" << endl;
exit(EXIT_FAILURE);
}

// Create CPP object.
Sample obj(42);

// Convert to JSCValue object and call 'fileInfo' function.
ret = jsc_value_function_call(fileInfo, JSC_TYPE_VALUE, obj.toJSObject(jsContext), G_TYPE_NONE);
cout << "ret: [" << jsc_value_to_string(ret) << "]" << endl;

return 0;
}

注意:在上面的示例中,我没有释放内存以避免增加复杂性。

方法 Sample::toJSObject将您的 CPP 对象转换为 JSCValue 对象。然后函数调用 jsc_value_function_call(fileInfo, JSC_TYPE_VALUE, obj.toJSObject(jsContext), G_TYPE_NONE);执行函数 fileInfo (之前在此 JavaScript 上下文中加载)并传递 CPP 对象的“强制转换”版本。执行此程序后的结果是:
ret: [fileInfo: 42]

关于javascript - 如何使用 JavaScriptCore 将 C++ 对象传递给 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57003419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com