[英]How to call native functions from a VM?
本机是指用 C++ 或 C 编写的
我正在制作一种基于 Java 的编程语言,因为它有一个 VM 和一个字节码编译器语言。
实现语言的特性,例如for
循环、变量、算术等等,对我来说不是问题; 但是,执行像 Java 这样的本机函数可以。
我需要本机函数,以便使用我的语言编写的程序能够创建窗口、与硬件和操作系统交互,以及做任何不是简单数学的事情。
我听说过JNI ,它确实看起来像是我想要的东西,但是,我不确定如何实现这样的东西。
由于我的 VM 是用 C++ 实现的,我知道我可以在编译时拥有它#include
我的本机函数的 hpp 文件,然后它可以动态加载dll
的或so
的,但是,这似乎并不真正喜欢一个很好的解决方案,因为每次您希望它能够执行另一个本机功能时都必须重新编译 VM。
问题归结为:C++ 程序(VM)如何动态地(在运行时,按照字节码的指示,更准确地说)加载带有 C++ 函数的库,然后执行这些函数而不在某些头文件中预先声明它们文件?
我还没有看到讨论过的一个主题是如何将新语言 VM 函数调用中的参数传递给 C++ 堆栈,以及如何将 C++ 函数的返回值传递回你的 VM。
假设您想让 pow(3) 函数在您的新语言中可用。 提醒一下, pow() 签名是
double pow ( double base, double power )
最简单的方法是这样的
void
language::pow( VM * pVM )
{
double arg2 = pVM->PopDouble();
double arg1 = pVM->PopDouble();
double result = pow( arg1, arg2 );
pVM->PushDouble( result );
}
但这听起来不像你所追求的。 结合 dlopen() & dlsym() 得到你的东西
void
language::pow( VM * pVM )
{
double arg2 = pVM->PopDouble();
double arg1 = pVM->PopDouble();
void *handle = dlopen("libm", RTLD_LAZY);
if (!handle) { /*...return; ...*/ }
typedef double (* pfPow ) ( double, double );
pfPow pPow = (pfPow) dlsym(handle, "pow");
if (!pPow) { /*...return; ...*/ }
double result = (* pPow )( arg1, arg2 );
pVM->PushDouble( result );
}
但这更糟。 对于您希望您的语言能够访问的每个 C++ 函数,您仍然需要一个存根函数。
听起来你希望你的语言有类似的东西
double result = eval_double( "libm", "pow", arg1, arg2 );
我不知道如何在 C++ 中实现它。 Varags 支持获取任何类型的 C++ 参数。 但是没有用于推送任意类型的 C++ 参数的 API。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.