call-c-from-myrddin.rst 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. 在 Myrddin 中调用 C 函数
  2. ==========================
  3. Myrddin 的实现是兼容 C ABI 的(见 https://myrlang.org/ ``C Binding`` 一节),我就试一下调用 C 的函数。
  4. 我写个 Myrddin 源程序 hello.myr::
  5. use std
  6. extern const greet: (->void)
  7. extern const sqrtf: (x:flt32 -> flt32)
  8. extern const memset: (buf: void#, c: int, sz: uint64 -> void)
  9. const main = {
  10. var buf: int[64]
  11. greet()
  12. std.put("Myrddin std.put\n")
  13. std.put("sqrt(9) is {}\n", sqrtf(9.0))
  14. memset((&buf: void#), 0x55, 64*4)
  15. for var i = 0; i < 64; i++
  16. std.put("{} ", buf[i])
  17. ;;
  18. std.put("\n")
  19. }
  20. Myrddin 有 ``void#`` (即 C 里面的 ``void*``),但是没有隐式类型转换,所以要显式地将 buf 转为 ``void#``. 此外,我暂时还不知道 Myrddin 里面有没有 sizeof, 所以直接把数组的大小 ``64*4`` 写进 memset 的参数里面。
  21. greet() 是我自己定义的函数,在 greet.c 里面::
  22. #include <stdio.h>
  23. void greet()
  24. {
  25. puts("Hello world!");
  26. }
  27. 首先把目标文件 ``*.o`` 编译出来::
  28. gcc -c greet.c
  29. 6m hello.myr
  30. 最后手动链接,我们用 Myrddin 的运行时,和 C 的 libc 和 libm::
  31. 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
  32. 注意 -dynamic-linker 参数,否则链接出来的程序不能运行。
  33. 最后运行 hello, 正常输出结果。