使用PLT-Scheme外部函数接口调用mysql_real_escape_string

时间:2009-11-08 20:11:21

标签: racket ffi

使用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.

4 个答案:

答案 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)