0

使用 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 的有效连接,而 escape-string 定义为

(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 的定义是否正确。

任何帮助,将不胜感激。

问候,

拉尔夫·S。

4

4 回答 4

1

通常,_ptr在外部 (C) 代码需要指针的地方使用参数,但您希望避免在 Scheme 端处理指针。例如,(_ptr o _int)当您有一个外部函数需要一个整数指针并将其设置为某个值(通常称为“输出指针”因此称为“ o”)时,将使用它。_fun安排一个指针的分配,并在调用完成时取消对它的引用——但可能令人困惑的是你需要用一个名称来获取这个值,否则它就会被丢弃。这是执行此操作的示例:

(_fun [r : (_ptr o _int)] -> _void -> r)

您应该将其解读为:将指向整数的指针传递给外部函数,并将结果值作为r. 外部函数返回 void,但它被忽略,而是返回 的值r,有效地取消引用指针。请注意,由于这是一个输出指针,因此您无需指定它的输入值。例如,如果该类型用于某些foo绑定,则foo不需要任何参数。

A(_ptr i _int)不同:生成的函数需要一个整数,在调​​用时分配一个指针并将该指针传递给外部函数(因此 C 代码仍然看到 an int*)然后在调用后丢弃该指针。这里的目的是让这些函数的使用变得容易,而无需自己进行繁琐的分配。请注意,在这种情况下,这确实对应于生成的 Scheme 函数的输入,但不对应于以后可以使用的值。

最后,(_ptr io _int)是两者的结合:Scheme 函数将期望一个整数,将分配一个指针并将给定的整数放入其中,调用 C 函数并将该指针交给它,然后取消引用它并给出结果。例如,如果你有这个 C 函数:

void inc(int* p) { (*p)++; }

那么这将是一个合适的方案定义:

(define inc
  (get-ffi-obj 'inc "foo.so"
                (_fun [r : (_ptr io _int)] -> _void -> r)))
于 2009-11-08T21:40:35.640 回答
0

You may find one of these helpful:

于 2009-11-26T09:10:48.903 回答
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"
于 2009-11-09T19:32:33.257 回答
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?海事组织是这样的

(define r (setstring ???))
(do-something-with-r ...

或这个

(let ((r (setstring ???))) 
  (do-something-with-r ...

应该管用。但是,我只是不知道该作为参数传递什么???设置字符串。

于 2009-11-09T10:52:34.383 回答