我正在研究Red/System如何与Windows DLL,Linux/Android .so共享库和OS/X .dylib中的C库函数挂钩,#import
语法如下:
#import [ "libc.so.6" cdecl [ allocate: "malloc" [ size [integer!] return: [byte-ptr!] ] free: "free" [ block [byte-ptr!] ] /* ... */ ]
适用于所有基本类型,但是当函数需要指向指针的指针时,您会怎么做?例如,如果你试图绑定到getline()
具有原型的东西:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
调用它的一种方法(我想称之为...的方式)是传入的lineptr不是预分配的缓冲区,而是null
.在这种情况下,getline为您分配缓冲区并修改char*,使其不再为null.
作为第一次尝试,我做了:
getline: "getline" [ lineptr [byte-ptr!] ;-- char ** n [pointer! [integer!]] ;-- size_t * stream [byte-ptr!] ;-- FILE * return: [integer!] ;-- ssize_t ]
但由于没有类似的东西pointer! [c-string!]
,我不知道怎么称呼它.我可以获取c-string!
局部变量的地址并以byte-ptr!
某种方式传递它吗?
Red/System [ Title: "derp" ] #import [ LIBC-file cdecl [ _fdopen: "fdopen" [ fd [integer!] type [c-string!] return: [pointer! [byte!]] ] _getline: "getline" [ line [pointer! [integer!]] n [pointer! [integer!]] stream [pointer! [byte!]] return: [integer!] ] ] ] getline: func [ stream [pointer! [byte!]] return: [c-string!] /local line [integer!] n [integer!] ] [ line: 0 n: 0 _getline :line :n stream as c-string! line ] stream: _fdopen 0 "r" line: getline stream print line
这有效.