2010-11-23 22 views
7

我想了解weave.inline在我的Python程序中打包C代碼。下面的代碼簡單地取numpy的陣列和multiplicates所有元素通過2.如何將scipy.weave.inline與外部C庫一起使用?

inl.py

import numpy 
import scipy.weave 

a = numpy.array([1.0, 2.0, 3.0]) 
N = a.shape[0] 

print a 
code = \ 
    """ 
    int i; 
    for(i = 0; i < N; i++) 
    { 
    a[i] = a[i] * 2; 
    } 
    """ 

scipy.weave.inline(code, ['a','N']) 
print a 

然後我想攜帶來自內聯代碼一些功能外部庫。讓它成爲由2瑣碎乘法所以我創建兩個文件:

mult.c

#include "mult.h" 

float mult(float n) 
{ 
    return n * 2; 
} 

mult.h

float inc(float n); 

現在我想使用的功能MULT在我的內聯代碼中。但我不知道如何將我的C文件與Python內聯代碼鏈接起來。我嘗試將C文件編譯爲共享庫,並將它們作爲頭文件和庫進行編織,但這是徒勞的。有什麼建議麼?

回答

7

我已經成功地做到了這一點,通過weave.inline調用數學函數從R()代碼(在Ubuntu Linux操作系統)。

首先,將您的C函數編譯爲共享庫。就我而言,我抓住的R從CRAN近期發佈,並沒有

./configure --enable-R-static-lib --enable-static --with-readline=no 
cd src/nmath/standalone/ 
make 

您現在應該有一個名爲libRmath.so文件。如果libpath是與持有libRmath.so目錄中的字符串,你可以這樣做

code = 'return_val = pbinom(100, 20000, 100./20000., 0, 1);' 
support_code = 'extern "C" double pbinom(double x, double n, double p, int lower_tail, int log_p);' 
weave.inline(code, support_code=support_code, 
    library_dirs=[libpath], libraries=["Rmath"], runtime_library_dirs=[libpath]) 

注意兩件事情。標題聲明必須在support_code而不是code(我不知道爲什麼),並且它們必須以extern "C"作爲前綴,因爲它們是C代碼,而不是C++(這是標準的)。應該可以包含頭文件而不是使用support_code(請查看weave.inline的文檔),但我沒有嘗試過。庫名稱爲Rmath,但共享庫文件爲libRmath.so,採用通常的Unix約定。並指定庫的路徑兩次,一次用於鏈接,一次用於執行。

希望這會有所幫助!

1

對不起,我不知道如何做到這一點與weave。 然而,請參閱SO simple-wrapping-of-c-code-with-cython

+0

我已經嘗試了像Cython,ctypes和SWIG這樣的C/Python綁定。編織看起來像是將Numpy數組傳遞給C的最簡單方式,所以我想找到一種在其代碼中使用外部庫的方法。另外,我已經有了一段C編碼 - 並且它很好地工作。無論如何,謝謝。 – user517893 2010-11-27 04:43:52

1

把mult.c和mult.h的源稱爲extra_code一個String對象,然後添加下面的行放在.weave調用

support_code=extra_code, 

還有包括標準庫如下的選項:

headers = ["<math.h>"] 

享受

相關問題