使用PLT-Scheme-FFI,我想调用C函数
unsigned long mysql_real_escape_string(MYSQL *con, char *to, const char *from, unsigned long length)
从方案程序继续使用调用者内部的结果字符串'to'。计划程序的调用将如下:
(define-values (to) (escape-string con ??? from (+ (string-length from) 1)))
其中con是与MySQL-DB的有效连接,而转义字符串由
定义(define escape-string (get-ffi-obj "mysql_real_escape_string" libmysql
(_fun (con to from length) ::
(con : _pointer)
(to : (_ptr io _byte))
(from : _string)
(length : _ulong)
-> (res : _ulong)
-> (values out))))
问题是,我不知道要传递什么'???'当调用escape-string时,我也不知道escape-string的定义是否正确。
任何帮助都将不胜感激。
此致
Ralf S.
答案 0 :(得分:1)
通常,_ptr
参数用于外部(C)代码需要指针的位置,但是您希望避免处理Scheme方面的指针。例如,如果您有一个需要整数指针的外部函数并将其设置为某个值(通常称为“输出指针”,因此称为“(_ptr o _int)
”),则会使用o
。 _fun
安排指针的分配,并在调用完成后取消引用它 - 但可能令人困惑的是你需要用一个名字来获取这个值,否则就会被删除。以下是执行此操作的示例:
(_fun [r : (_ptr o _int)] -> _void -> r)
您应该将其读作:将指向整数的指针传递给外部函数,并将结果值作为r
使用。外部函数返回void,但忽略了它,而是返回r
的值,有效地解除引用指针。请注意,由于这是输出指针,因此您无需指定它的输入值。例如,如果该类型用于某些foo
绑定,那么foo
会期望没有参数。
(_ptr i _int)
是不同的:结果函数会期望一个整数,在调用时分配一个指针并将该指针传递给外部函数(所以C代码仍然看到int*
)然后丢弃这个通话后的指针。这里的目的是让您轻松使用这些功能而无需自己进行繁琐的分配。请注意,在这种情况下,此 对应于生成的Scheme函数的输入,但不对应于稍后可以使用的值。
最后,(_ptr io _int)
是两者的组合:Scheme函数将期望一个整数,将分配一个指针并将给定的整数放入其中,调用C函数并将其交给指针,然后取消引用它并给你结果。例如,如果你有这个C函数:
void inc(int* p) { (*p)++; }
然后这将是一个合适的Scheme定义:
(define inc
(get-ffi-obj 'inc "foo.so"
(_fun [r : (_ptr io _int)] -> _void -> r)))
答案 1 :(得分:0)
对格式感到抱歉。当我点击评论框上的提交按钮时,它看起来完全不同: - )
无论如何,这里又是:
......但是下面的C函数怎么样:
void setstring(char* str) { strcpy(str, "foo"); }
以下方案定义是否正确?
(define setstring
(get-ffi-obj 'setstring "foo.so"
(_fun [r : (_ptr io _byte)] -> void -> r)))
如果定义没问题,我如何调用Scheme中的setstring,以便我可以继续使用结果r? IMO是这样的
(define r (setstring ???))
(do-something-with-r ...
或者
(let ((r (setstring ???)))
(do-something-with-r ...
应该有效。但是,我只是不知道要传递什么作为参数???设置字符串。
答案 2 :(得分:0)
我明白了。 C函数的合适的Scheme定义
void setstring(char* str) { strcpy(str, "foo"); }
包含在动态库'lib.so'中
(define setstring
(get-ffi-obj 'setstring "lib.so"
(_fun (r : _u8vector) -> _void -> r))))
它可以被称为例如像这样
> (setstring (make-u8vector 5))
打印
> #"foo\0\0"
答案 3 :(得分:0)