2009-11-08 23 views
0

使用PLT-計劃-FFI mysql_real_escape_string,我想打電話從一個計劃程序的C函數調用使用PLT-計劃對外功能接口

unsigned long mysql_real_escape_string(MYSQL *con, char *to, const char *from, unsigned long length) 

,並繼續使用生成的字符串「到」裏面呼叫者,召集者。該計劃過程的調用會是這樣的:

(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的定義是否正確。

任何幫助,將不勝感激。

問候,

拉爾夫S.

回答

1

一般來說,使用_ptr參數,其中外資(C)代碼期望一個指針,但要避免處理上的計劃方面的指針。例如,當您有一個需要整數指針的外部函數並將其設置爲某個值(通常稱爲「輸出指針」,因此爲「o」)時,將使用(_ptr o _int)_fun安排了一個指針的分配,並在調用完成後將其解引用 - 但可能會讓人困惑的是您需要用名稱獲取該值,否則它將被丟棄。下面是這樣一個例子:

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

您應該讀這樣的:一個指針傳遞到一個整數外國功能,並提供爲r所得到的值。外部函數返回void,但忽略它,而是返回值r,有效地解引用指針。請注意,由於這是一個輸出指針,因此不需要指定它的輸入值。例如,如果該類型用於某個foo綁定,則foo會預期沒有參數。

(_ptr i _int)一個是不同的:所得到的功能所期望的整數,調用時分配指針和該指針傳遞給外國函數(因此C代碼仍然看到一個int*)然後丟棄呼叫之後該指針。這裏的目的是讓您輕鬆使用這些功能,而無需自己進行繁瑣的配置。請注意,在這種情況下,此確實與對應的是生成的Scheme函數的輸入,但不對應於稍後可以使用的值。

最後,(_ptr io _int)是兩者的組合:計劃功能將期待一個整數,將分配一個指針,並把它給定的整數,調用C函數,並把它該指針,然後取消對它的引用,給你結果。舉例來說,如果你有這樣的C函數:

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

那麼這將是它一個合適的方案定義:

(define inc 
    (get-ffi-obj 'inc "foo.so" 
       (_fun [r : (_ptr io _int)] -> _void -> r))) 
+0

感謝您的答覆。我想我理解這個例子。但是下面的C函數怎麼樣: void setstring(char * str){strcpy(str,「foo」); } 以下Scheme定義是否正確? (定義了setString (GET-FFI-OBJ「的SetString 「foo.so」 (_fun [R:(_ptr IO _byte)] - >空 - > R))) 如果定義是確定的,該怎麼辦我從Scheme中調用setstring,以便我可以繼續處理結果r?國際海事組織是這樣的 (定義R(的SetString ???)) 或本 (LET((R(的SetString ???)))... 應該工作。但是,我只是不知道要傳遞什麼作爲參數???設置字符串。 –

+0

幾乎不可能閱讀本評論中的代碼,以及在評論中撰寫回復。您可以將此作爲新問題發佈嗎?(或者繼續閱讀PLT郵件列表。) –

0

很抱歉的格式。當我點擊評論框提交按鈕它看起來完全不同:-)

不管怎樣,這裏要再次重申:

...但是,我們下面的C函數:

void setstring(char* str) { strcpy(str, "foo"); } 

下面的Scheme定義是否正確?

(define setstring 
    (get-ffi-obj 'setstring "foo.so" 
       (_fun [r : (_ptr io _byte)] -> void -> r))) 

如果定義是確定的,我怎麼叫,從方案的SetString,這樣我可以繼續執行結果R工作?國際海事組織是這樣的

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

或本

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

應該工作。但是,我只是不知道要傳遞什麼參數?設置字符串。

0

我想通了。對於被包含在「lib.so」的動態庫中的C-功能

void setstring(char* str) { strcpy(str, "foo"); } 

一種合適的方案定義是

(define setstring 
    (get-ffi-obj 'setstring "lib.so" 
       (_fun (r : _u8vector) -> _void -> r)))) 

它可以例如被稱爲這樣

> (setstring (make-u8vector 5)) 

它打印

> #"foo\0\0"