如何向自定义虚拟机公开 C 函数?
我正在开发一个虚拟机,我希望能够与 C 接口。换句话说,将虚拟机函数暴露给 C 代码相当容易,但我无法理解的是将 C 函数暴露给虚拟机。
我希望能够向虚拟机动态注册 C 函数,如下所示:
vm_register(printf);
然后在我的虚拟机中,将参数推送到堆栈,并且:
call printf
问题是,不知道函数需要多少个参数,以及什么参数类型,我不确定可以使用函数指针。
是否有可以在这种情况下使用的通用函数指针类型?有人可以引导我走向正确的方向吗?
I'm working on a virtual machine which I would like to be able to interface with C. Going the other way and exposing virtual machine functions to C code is fairly easy, what I can't wrap my head around is exposing C functions to a virtual machine.
I'd like to be able to dynamically register C functions with the virtual machine like so:
vm_register(printf);
Then in my virtual machine, push the arguments to the stack, and:
call printf
The problem is that without knowing how many arguments the function requires, and of what type, I'm not sure function pointers can be used.
Is there a generic function pointer type that can be used in this situation? Can someone steer me in the right direction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一般的答案是你必须自己使用汇编来实现它。与 libc 链接后,您就获得了要调用的函数的地址,并且必须手动将参数传递给该函数(使用虚拟机运行的任何平台的调用约定)。
幸运的是,有一个库 libffi 可以完全满足您的需求。它也很容易使用,它的源代码包括一些文档和示例。如果您有兴趣了解它是如何工作的,可以查看它的代码(例如 使用 unix 调用约定调用函数)。
关于参数类型,您通常必须让用户为您描述它们,然后盲目地接受它们,并将它们进一步传递给 libffi(如果没有 libffi,则传递给硬件)。另一种方法是解析要调用的函数的 C 头文件,这不太容易出错 - 但无论如何,实际上没有安全的方法,因为函数的二进制代码没有描述其接口(使用 printf 及其可变参数列表更是如此)。
The general answer is that you have to implement it yourself using assembly. After linking with libc, you have the address of the function you want to call, and you have to pass the parameters to the function manually (using the calling convention of whatever platform your virtual machine is running on).
Luckily there's a library, libffi, that does exactly what you want. It's pretty easy to use as well, its source includes some documentation and examples. If you're interested to see how it works, you can take a look at its code (e.g. calling a function using the unix calling convention).
Regarding the parameter types, you usually have to let the user describe them for you and blindly accept that and pass them further on to libffi (or to the hardware if you do it without libffi). Another way would be to parse the C header file for the function to call, which is less error prone - but in any case, there's really no safe way as the binary code for the function doesn't describe its interface (with printf and its variable parameter list even more so).