c++ - 动态 C++ 函数参数

标签 c++ function

这很可能是错误的标题,但我不知道如何描述它。我想做的是从我的脚本语言(在虚拟机中运行)调用 C++ 函数。我在弄清楚如何将参数传递给函数时遇到了一些麻烦。

到目前为止我最好的解决方案是这样做:

void func(int a) {

// Start param copy
char c;
char* par_start = &c - sizeof(char) - getCurrentFuncParamOffset();
copyCurrentParams(par_start);
// End copy

// Code

}

然后,为了调用该函数,我首先将其公开给虚拟机,并为其提供参数。这是一些缩短的代码,但所有内容都被转换为 void(*),因此可以将其存储在哈希表中。

EXPOSE(test, int);
vm.call("test", 12)

EXPOSE 获取指向函数 test 的指针,并存储它需要调用一个函数。它将指针作为 void(*)() 存储在哈希表中,以便当我想要调用它时,我可以从虚拟机进行调用并解决它。然后函数内部的代码(我从问题中的宏扩展而来)会将调用 VM 传入的参数复制到函数的参数中。

这可行,但它不是最优雅的解决方案,特别是因为我必须为每个要公开用于脚本编写的函数调用一个宏。有更好的解决方案吗?谢谢。

最佳答案

您也可以使用 C++ 提供的功能。这是我整理的一个小例子。

class ScriptObj {}; // Your type that encapsulates script objects. 
                    // May be as simple as an integer or a string,
                    // or arbitrarily complex like PyObj

template <typename T> T from_script(ScriptObj); // conversion to and from
template <typename T> ScriptObj to_script(T);   // C++ types. You provide
                                                // specialized implementations.
                                                // Bad conversions should throw.

// Abstract base class for C++ functions callable from the scripts.
// The scripting engine should pass a vector of parameters and a pointer to result.
struct script2cxx
{
    virtual ~script2cxx() {}
    virtual ScriptObj operator()(const std::vector<ScriptObj>& params) = 0;
};    


// Concrete class that exposes a C++ function to the script engine.
template <class Res, class ... Param>
struct script2cxx_impl : script2cxx
{

    using funcType = Res(*)(Param...);

    virtual ScriptObj operator()(const std::vector<ScriptObj>& params)
    {
        if (sizeof...(Param) != params.size())
            throw std::domain_error("Invalid size of parameter array");
        return to_script<Res>(call_impl<std::tuple<Param...>>(func, params, std::make_index_sequence<sizeof...(Param)>()));
    }

    template <class Tuple, std::size_t... N>
        Res call_impl(funcType func, const std::vector<ScriptObj>& params, std::index_sequence<N...>)
        {
            return func(from_script<typename std::tuple_element<N, Tuple>::type>(params[N])...);
        };

    funcType func;

    script2cxx_impl(funcType func) : func(func) {}
};

// a helper biold function
template  <class Res, class ... Param>
auto expose(Res(*func)(Param...)) {
    return new script2cxx_impl<Res, Param...>(func);
}

现在您可以构建 script2cxx (智能)指针的映射,并使用脚本对象的 vector 调用它们。

 std::map<std::string, std::unique_ptr<script2cxx>> exposed;


 int foo(double, char[], int**) {...}

 // below is the only line you need to add
 // if you want to expose any standalone C++ function.
 // no boilerplate.

 exposed["foo"]=expose(foo); // you can wrap this in a macro if you want

并称呼他们:

 std::vector<ScriptObj> somevector = ...;
 std::string somestring = ...;
 (*exposed[somestring])(somevector); 

在制作这个示例时,没有不安全的强制转换和/或 void 指针受到损害。

关于c++ - 动态 C++ 函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41549827/

相关文章:

function - 如何使用关联常量来定义数组的长度?

PHP函数返回0,不知道为什么

c++ - 功能永远不会在 Switch 语句中结束?

javascript - 这个 swipe.js 函数返回了什么?

c++ - std::exception 和 "..."之间的区别

c++ - 多个源文件可执行文件比单个源文件可执行文件慢

c++ - 是否存在代码在 c++11 中有序列点但在 c++03 中没有的情况?

c++ - 在 C++ 中部分截断流(fstream 或 ofstream)

c# - 如何正确继承Unity的Awake()、Start()和Update、FixedUpdate()等回调函数?

c++ - 使用 scons 构建时无法使用 IAR arm 编译器进行编译...许可证检查失败