2022년 5월 3일 화요일

플러그인 개발을 위한 자바 스크립트와 C++ 연동 및 실행 방법

이 글은 자바스크립트(Javascript)와 C++ 연동 방법에 대한 내용을 간략히 공유한다. 가끔, 플러그인 등을 개발할 때, 외부 스크립트 코드와 연동해야할 경우가 있다. 이와 관련해, 필요한 내용이 무엇인지 알아본다.

자바스크립트 동작 방식은 다음과 같다.
자바스크립트 내부 구조
자바스크립트 실행 상태 예시

아래는 C++에서 자바스크립트를 호출하는 방법을 보여준다. 
#include "quickjspp.hpp"
#include <iostream>

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

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

void println(qjs::rest<std::string> args) {
    for (auto const & arg : args) std::cout << arg << " ";
    std::cout << "\n";
}

int main()
{
    qjs::Runtime runtime;
    qjs::Context context(runtime);
    try
    {
        // C++클래스 정의 
        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");

        // 자바스크립트 모듈 임포트
        context.eval(R"xxx(
            import * as my from 'MyModule';
            globalThis.my = my;
        )xxx", "<import>", JS_EVAL_TYPE_MODULE);

        // 자바스크립트 코드 호출 및 실행.
        // C++에서 정의된 클래스를 자바스크립트에서 생성, 호출할 수 있다.
        context.eval(R"xxx(
            let v1 = new my.MyClass();
            v1.member_variable = 1;
            let v2 = new my.MyClassA([1,2,3]);
            function my_callback(str) {
              my.println("at callback:", v2.member_function(str));
            }
        )xxx");

        // callback
        auto cb = (std::function<void(const std::string&)>) context.eval("my_callback");
        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;
    }
}

이 코드 실행을 위해서는 quickjspp 라이브러리가 필요하다. 아래 링크를 참고해 설치하고, 실행하면 된다. 

레퍼런스

댓글 없음:

댓글 쓰기