2013-12-12 27 views
3

我有在它的API中的一個使用一個函數 hello_printf(常量字符*格式,...)一個簡單的庫。而在下使用 這個庫,我使用的庫指向hello_printf的函數指針 的printf在外部應用程序和代碼無縫工作。提供的ctypes的函數外部定義的C/C++庫

hello_printf不是API,但在一個 API的的實施使用。原因是我希望使用庫的外部應用程序 提供printf(外部綁定)的實現。

現在我想在Python中使用這個庫,我使用的ctypes調用API的,但我無法找到一個方法來找到提供的功能外結合與ctypes的。 即將hello_printf()指向libc的printf,使得「hello_printf = libc.printf」。

+0

這幾乎覆蓋http://stackoverflow.com/questions/16513708/how-to-export-ac-array-to -python/16525801#16525801和http://stackoverflow.com/questions/544173/mapping-a-global-variable-from-a-shared-library-with-ctypes,爲了完整性提及。 –

回答

3

您正在尋找的ctypes數據類型的in_dll方法。

C:

#include <stdlib.h> 

int (*hello_printf)(const char *format, ...) = NULL; 

int test(const char *str, int n) { 
    if (hello_printf == NULL) 
     return -1; 
    hello_printf(str, n); 
    return 0; 
} 

ctypes的:

from ctypes import * 

cglobals = CDLL(None) 
lib = CDLL("./lib.so") 

hello_printf = c_void_p.in_dll(lib, "hello_printf") 
hello_printf.value = cast(cglobals.printf, c_void_p).value 

>>> lib.test("spam %d\n", 1) 
spam 1 
0 
+0

謝謝。該解決方案有效。非常感激。 這個解決方案只有一個小問題。 hello_printf函數解析爲「lib.so」並且工作完美。在我的情況下,lib.so也通過dlopen打開另一個動態庫,即lib_runtime.so,它們也使用hello_printf。有沒有什麼方法可以將新函數公開到lib.so調用的其他庫中,而不是從python ctypes中調用。 – Akamai

+0

你的意思是把標誌'RTLD_GLOBAL'傳遞給'dlopen',即'lib = CDLL('./ lib.so',RTLD_GLOBAL)''嗎? Linux上默認爲'RTLD_LOCAL'。 – eryksun

+0

非常感謝。你是對的。我只是使用默認模式,因此它沒有得到解決的其他庫。它工作完美。再次感謝你的幫助。 – Akamai