vimacs's personal siteWritten with Vim and Emacs

在 Myrddin 中调用 C 函数

Myrddin 的实现是兼容 C ABI 的(见 https://myrlang.org/ C Binding 一节),我就试一下调用 C 的函数。

我写个 Myrddin 源程序 hello.myr:

use std

extern const greet: (->void)
extern const sqrtf: (x:flt32 -> flt32)
extern const memset: (buf: void#, c: int, sz: uint64 -> void)

const main = {
      var buf: int[64]
      greet()
      std.put("Myrddin std.put\n")
      std.put("sqrt(9) is {}\n", sqrtf(9.0))
      memset((&buf: void#), 0x55, 64*4)
      for var i = 0; i < 64; i++
              std.put("{} ", buf[i])
      ;;
      std.put("\n")
}

Myrddin 有 void# (即 C 里面的 void*),但是没有隐式类型转换,所以要显式地将 buf 转为 void#. 此外,我暂时还不知道 Myrddin 里面有没有 sizeof, 所以直接把数组的大小 64*4 写进 memset 的参数里面。

greet() 是我自己定义的函数,在 greet.c 里面:

#include <stdio.h>

void greet()
{
      puts("Hello world!");
}

首先把目标文件 *.o 编译出来:

gcc -c greet.c
6m hello.myr

最后手动链接,我们用 Myrddin 的运行时,和 C 的 libc 和 libm:

ld -o hello hello.o greet.o /usr/local/lib/myr/libstd.a /usr/local/lib/myr/libsys.a /usr/local/lib/myr/_myrrt.o -lc -lm -dynamic-linker /usr/lib64/ld-linux-x86-64.so.2

注意 -dynamic-linker 参数,否则链接出来的程序不能运行。

最后运行 hello, 正常输出结果。