2021-04-14 quickjs調(diào)用類的非靜態(tài)成員函數(shù)

有這樣一個(gè)需求:多線程條件下執(zhí)行交易,每個(gè)交易都會(huì)通過quickjs回調(diào)c++代碼的函數(shù),而這個(gè)函數(shù)使用的數(shù)據(jù)又來自于當(dāng)前的交易
首先不考慮用全局變量來保存交易的數(shù)據(jù),因?yàn)閖s回調(diào)c函數(shù)的時(shí)候我們無法在回調(diào)函數(shù)中區(qū)分當(dāng)前屬于哪個(gè)交易,如果你總是把交易的id通過回調(diào)函數(shù)傳遞過來也是可以實(shí)現(xiàn),只是這樣函數(shù)就多了個(gè)參數(shù),寫js代碼的人無法理解。
一個(gè)簡(jiǎn)單的思路是c代碼創(chuàng)建交易的類,然后把類的函數(shù)傳遞給quickjs,然后在js中調(diào)用這個(gè)類的函數(shù),但是這個(gè)實(shí)現(xiàn)不了,因?yàn)閝uickjs沒有注入非靜態(tài)成員函數(shù)的接口,其原因文章非static成員函數(shù)通過類名::來調(diào)用,空指針調(diào)用成員方法不出錯(cuò)!講解的比較清楚
換個(gè)思路,我們先用js創(chuàng)建這個(gè)類,然后調(diào)用eval把類的數(shù)據(jù)傳遞給它,這樣調(diào)用這個(gè)類的非靜態(tài)成員函數(shù)的時(shí)候就可以正確訪問到數(shù)據(jù)了,我們直接修改文件example.cpp
具體實(shí)現(xiàn)如下:

class MyClass
{
public:
    MyClass() {}
    MyClass(std::vector<int>) {}

    double member_variable = 5.5;
    std::string member_function(const std::string& s) { return "Hello, " + s + " " + std::to_string(member_variable); }
};

void println(const std::string& str) { std::cout << str << std::endl; }

MyClass* pGlobalMyClass = NULL;

int main()
{
    qjs::Runtime runtime;
    qjs::Context context(runtime);
    try
    {
        // export classes as a module
        auto& module = context.addModule("MyModule");
        module.function<&println>("println");
        module.class_<MyClass>("MyClass")
                .constructor<>()
                .constructor<std::vector<int>>("MyClassA")
                .fun<&MyClass::member_variable>("member_variable")
                .fun<&MyClass::member_function>("member_function");
        // import module
        context.eval("import * as my from 'MyModule'; globalThis.my = my;", "<import>", JS_EVAL_TYPE_MODULE);
        // evaluate js code
        context.eval(
                     "let v1 = new my.MyClass();" "\n"
        );
        context.eval(
                "function my_callback(str) {" "\n"
                "  my.println(v1.member_function(str));" "\n"
                "}" "\n"
        );
        // callback
        auto cb = (std::function<void(const std::string&)>) context.eval("my_callback");
        cb("world");

        context.eval("v1.member_variable=" + std::to_string(3) + ";\n");

        cb("world");
    }
    catch(qjs::exception)
    {
        auto exc = context.getException();
        std::cerr << (std::string) exc << std::endl;
        if((bool) exc["stack"])
            std::cerr << (std::string) exc["stack"] << std::endl;
        return 1;
    }
}

執(zhí)行結(jié)果如下:

Hello, world 5.500000
Hello, world 3.000000

這樣一來,每個(gè)交易的數(shù)據(jù)都是獨(dú)立在quickjs中執(zhí)行,實(shí)現(xiàn)了并行處理的目的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容