这里有两个问题:一个是如何将数据数组传递给 C 函数,另一个是如何从 C 函数中获取数据数组。
对于第一个问题,您需要将每个 JS 字符串转换为 C 字符串,为包含每个此类 C 字符串的数组分配 C 内存,并将值写入数组 - 然后您可以将其传递给您的函数.
例如:
emcc 标志:
-s EXPORTED_FUNCTIONS="['UTF8ToString','stringToUTF8Array','lengthBytesUTF8']"
-s EXTRA_EXPORTED_RUNTIME_METHODS="['_free','_malloc','setValue']"
Javascript:
// convert a Javascript string to a C string
function str2C(s) {
var size = lengthBytesUTF8(s) + 1;
var ret = _malloc(size);
stringToUTF8Array(s, HEAP8, ret, size);
return ret;
}
function run_with_strings(strings) {
let c_strings = strings.map(x => str2C(x));
// allocate and populate the array. adapted from https://stackoverflow.com/a/23917034
let c_arr = _malloc(c_strings.length*4); // 4-bytes per pointer
c_strings.forEach(function(x, i) {
Module.setValue(argsC + i * 4, x, "i32");
});
// invoke our C function
let rc = myCFunc(c_strings.length, c_arr);
// free c_strings
for(let i = 0; i < c_strings.length; i++)
_free(c_strings[i]);
// free c_arr
_free(c_arr);
// return
return rc;
}
对于第二个问题,您的 C 函数原样可能难以使用,因为它不返回项目数(尽管我认为您可以推断出最后一项是否为 NULL 并且没有其他项为 NULL)。一种解决方案是让您的函数返回一个不透明的指针,然后可以将其反馈到一些辅助函数中,例如:
在 C 中:
struct myCFuncReturnValue {
char **values;
unsigned int count;
};
struct myCFuncReturnValue *myCFunc(char **input) {
struct myCFuncReturnValue *p = calloc(1, sizeof(*p));
...
p->count = ...;
p->values = ...;
return p;
}
char *myCFunc_value(struct myCFuncReturnValue *p, unsigned int i) {
return i < p->count ? p->values[i] : NULL;
}
unsigned int myCFunc_count(struct myCFuncReturnValue *p) {
return p->count;
}
void myCFunc_destroy(struct myCFuncReturnValue *p) {
// maybe here you need to free each p->values[i];
free(p->values);
free(p);
}
Javascript:
// continuing with the rc value from run_with_strings():
for(let i = 0, j = myCFunc_count(rc); i < j; i++) {
let c_string = myCFunc_value(rc, i);
console.log(UTF8ToString(c_string));
}
myCFunc_destroy(rc);