Как вызывать функции WASI непосредственно на C с помощью wasi-sdk (проблема модуля импорта)
Я пытаюсь вызвать функцию WASI (fd_write) непосредственно в программе C, используя wasi-sdk. Это библиотека (lib.c):
#include <stdint.h>
struct Ciovec
{
uint8_t *buf;
uint32_t buf_len;
};
uint16_t fd_write(uint32_t fd, struct Ciovec *iovs_ptr, uint32_t iovs_len, uint32_t *nwritten);
static char *str = "just testing\n";
void c_main()
{
struct Ciovec vec = { .buf = (uint8_t*)str, .buf_len = 13 };
uint32_t nwritten = 0;
fd_write(1, &vec, 1, &nwritten);
}
Теперь, если я построю это в статически подключаемой библиотеке с помощью wasi-sdk
~/wasi-sdk-11.0/bin/clang --sysroot ~/wasi-sdk-11.0/share/wasi-sysroot/ lib.c -c -o lib.o -fpic
Получаю вот такой вот: (wasm2wat --enable-all
выход)
(module
(type (;0;) (func))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(import "env" "__linear_memory" (memory (;0;) 1))
(import "env" "__indirect_function_table" (table (;0;) 0 funcref))
(import "env" "__stack_pointer" (global (;0;) (mut i32)))
(import "env" "fd_write" (func (;0;) (type 1)))
...)
Теперь эта строка импорта для fd_write
не является правильным. Насколько я понимаю, функции WASI нужно импортировать изwasi_snapshot_preview1
или wasi_unstable
(У меня нет источника для первого, я просто видел его в открытом коде, для второго см. Пример здесь, но я не уверен, как это сделать на C. Есть идеи?
2 ответа
Нашел ответ в исходном коде wasi-libc:
uint16_t fd_write(uint32_t fd, struct Ciovec *iovs_ptr, uint32_t iovs_len, uint32_t *nwritten)
__attribute__((
__import_module__("wasi_snapshot_preview1"),
__import_name__("fd_write"),
));
Создан Wasm:
(import "wasi_snapshot_preview1" "fd_write" (func $fd_write (type 1)))
Это все еще не работает, я понимаю undefined symbol: fd_write
ошибки, но, по крайней мере, я теперь знаю, как указать путь импорта.
Итак, я сделал это для работы:
#include <stdint.h>
#include <stdio.h>
extern uint16_t my_func()
__attribute__((
__import_module__("my_module"),
__import_name__("my_func"),
));
int main(){
my_func();
return 0;
}
Компилировать с
-Wl,--allow-undefined
Генерирует
(module
(type (;0;) (func (param i32 i32 i32) (result i32)))
(type (;1;) (func (param i32 i64 i32) (result i64)))
(type (;2;) (func (param i32 i32) (result i32)))
(type (;3;) (func (result i32)))
(type (;4;) (func (param i32)))
(type (;5;) (func (param i32) (result i32)))
(type (;6;) (func (param i32 i32 i32 i32) (result i32)))
(type (;7;) (func (param i32 i64 i32 i32) (result i32)))
(type (;8;) (func))
(import "wasi_unstable" "fd_prestat_get" (func $__wasi_fd_prestat_get (type 2)))
(import "wasi_unstable" "fd_prestat_dir_name" (func $__wasi_fd_prestat_dir_name (type 0)))
(import "my_module" "my_func" (func $my_func__ (type 3)))
(import "wasi_unstable" "proc_exit" (func $__wasi_proc_exit (type 4)))
(import "wasi_unstable" "fd_fdstat_get" (func $__wasi_fd_fdstat_get (type 2)))
(import "wasi_unstable" "fd_close" (func $__wasi_fd_close (type 5)))
(import "wasi_unstable" "fd_write" (func $__wasi_fd_write (type 6)))
(import "wasi_unstable" "fd_seek" (func $__wasi_fd_seek (type 7)))
(func $__wasm_call_ctors (type 8))
(func $undefined:__wasilibc_populate_environ (type 3) (result i32)