调用原生动态库 — 22 种语言用原生语法调用 C 库函数,无需手写汇编
从 VML 程序到原生动态库的完整调用路径
| SYSCALL | 编号 | 功能 | 参数 | 返回 |
|---|---|---|---|---|
| dl_open | #370 | 加载动态库 | R0 = 库路径字符串地址 | R0 = handle (非0成功) |
| dl_sym | #371 | 查找函数符号 | R0 = handle, R1 = 函数名字符串地址 | R0 = func_ptr_id |
| dl_close | #372 | 卸载动态库 | R0 = handle | — |
| native_call | #373 | 调用原生函数 (int 参数) | R0 = func_id, R1 = args_addr, R2 = arg_count, R3 = flags | R0 = int 返回值 |
| native_call_0 | #374 | 调用无参原生函数 | R0 = func_id | R0 = 返回值 |
| native_call_f | #375 | 调用原生函数 (float 参数) | R0 = func_id, R1 = args_addr, R2 = arg_count, R3 = flags | R0 = float 的 int32 位模式 |
支持 int/指针 参数传递,最多 8 个参数
| 寄存器 | 含义 | 说明 |
|---|---|---|
| R0 | func_ptr_id | 通过 dl_sym 获取的函数指针 ID |
| R1 | args_addr | VML 内存中参数数组地址(每个参数 4 字节) |
| R2 | arg_count | 参数数量(最大 8) |
| R3 | flags | 0 = int 返回, 1 = void 返回 |
; 1. 准备参数数组 (每个参数 4 字节)
MOVE R0, #640
STORE [R12-4], R0 ; arg[0] = 640 (宽度)
MOVE R0, #480
STORE [R12-8], R0 ; arg[1] = 480 (高度)
LOAD R0, title_str
STORE [R12-12], R0 ; arg[2] = title 指针
; 2. 调用 native_call
LOAD R0, [R12+glh_init_id] ; func_ptr_id
LOAD R1, R12
SUB R1, #12 ; args_addr = R12-12
MOVE R2, #3 ; 3 个参数
MOVE R3, #1 ; void 返回
SYSCALL #373 ; native_call
为 OpenGL 函数 (glRotatef, glVertex3f 等) 设计的 float 参数调用接口
| 寄存器 | 含义 | 说明 |
|---|---|---|
| R0 | func_ptr_id | 通过 dl_sym 获取的函数指针 ID |
| R1 | args_addr | VML 内存中参数数组地址(每个参数 4 字节 float 位模式) |
| R2 | arg_count | 参数数量(最大 8) |
| R3 | flags | 0 = float 返回, 1 = void 返回 |
; 1. 准备 float 参数 (使用 FSTORE 或手动构造位模式)
FLOAD F0, #0.5 ; angle = 0.5 弧度
FSTORE [R12-4], F0
FLOAD F0, #1.0
FSTORE [R12-8], F0 ; x = 1.0
FLOAD F0, #0.0
FSTORE [R12-12], F0 ; y = 0.0
FLOAD F0, #0.0
FSTORE [R12-16], F0 ; z = 0.0
; 2. 调用 native_call_f
LOAD R0, [R12+glh_rotatef_id]
LOAD R1, R12
SUB R1, #16 ; args_addr
MOVE R2, #4 ; 4 个 float 参数
MOVE R3, #1 ; void 返回
SYSCALL #375 ; native_call_f
BitConverter.Int32BitsToSingle → floatBitConverter.SingleToInt32Bits → 存入 R022 种语言调用同一个 VML FFI 封装库,实现 OpenGL 旋转立方体
void gl_setup();
int gl_should_close();
void gl_frame();
void gl_teardown();
int main() {
gl_setup();
while (!gl_should_close())
gl_frame();
gl_teardown();
}
DECLARE SUB gl_setup
DECLARE FUNCTION gl_should_close
DECLARE SUB gl_frame
DECLARE SUB gl_teardown
CALL gl_setup
WHILE gl_should_close() = 0
CALL gl_frame
WEND
CALL gl_teardown
program CubeDemo;
procedure gl_setup; forward;
function gl_should_close: integer; forward;
procedure gl_frame; forward;
procedure gl_teardown; forward;
begin
gl_setup;
while gl_should_close = 0 do
gl_frame;
gl_teardown;
end.
fn main() {
gl_setup();
while gl_should_close() == 0 {
gl_frame();
}
gl_teardown();
}
def gl_setup():
asm("CALL gl_setup_impl")
def gl_frame():
asm("CALL gl_frame_impl")
def gl_teardown():
asm("CALL gl_teardown_impl")
gl_setup()
for _ in range(2000):
gl_frame()
gl_teardown()
Python 编译器限制: def 内需要 asm 桥接到库标签,主代码调用正常
package main
func main() {
gl_setup()
for {
if gl_should_close() != 0 {
break
}
gl_frame()
}
gl_teardown()
}
| 语言 | 零 asm 调用 | 标签别名 | 说明 |
|---|---|---|---|
| C / C++ / Rust / Go / BASIC / Swift / Kotlin / JS / Scheme | ✅ | gl_setup 或 func_gl_setup | 直接调用,无需声明 |
| Pascal / C# / Java | ✅ | gl_setup / method_gl_setup | 需要 forward/extern 声明 |
| Lua | ✅ | func_gl_setup | 编译器自动添加 func_ 前缀 |
| Python | ⚠️ | gl_setup_impl | def 内需 asm 桥接,主代码正常 |
| Forth | ✅ | word_gl_setup | 编译器自动添加 word_ 前缀 |
| Ladder | ⚠️ | LADDER_GL_SETUP | 需 ASM 块,梯形图语言限制 |
如何编写和编译供 VML FFI 调用的原生 C 库
// 纯 float/int 参数,无结构体,便于 FFI 调用
void* glh_init(int w, int h, const char* title);
void glh_clear(float r, float g, float b, float a);
void glh_begin(int mode);
void glh_color3f(float r, float g, float b);
void glh_vertex3f(float x, float y, float z);
void glh_rotatef(float angle, float x, float y, float z);
void glh_translatef(float x, float y, float z);
void glh_end();
void glh_swap();
int glh_should_close();
float glh_get_time();
void glh_destroy();
void glh_draw_cube(float time);
# macOS — 编译为动态库
cc -shared -o Lib/opengl/libglhelper.dylib Lib/opengl/libglhelper.c \
-framework OpenGL -framework GLFW \
-I/opt/homebrew/include -L/opt/homebrew/lib
# Linux
cc -shared -fPIC -o Lib/opengl/libglhelper.so Lib/opengl/libglhelper.c \
-lGL -lglfw
# 然后编译 VML 程序并运行
vmltool Examples/OpenGL/cube_c.c -o cube_c.vml --mode os
consoleemulator -r cube_c.vml --mode os