2013-08-07 14 views
4

我已經說(在本例num_piezas)提交一個int簡單的工作程序的C++功能。從<code>Python</code>函數提交「INT」,並使用ctypes的(Python-> C++)「字符串」陣列

Foo.cpp中

#include <iostream> 

class Foo{ 
    public: 
     void bar(int number){ 
      printf("Number is: %d\n", number); 
     } 
}; 

extern "C" { 
    Foo* Foo_new(){ return new Foo(); } 
    void Foo_bar(Foo* foo, int number){ foo->bar(number); } 
} 

fooWrapper.py

from ctypes import cdll 
lib = cdll.LoadLibrary('./libfoo.so') 

class Foo(object): 
    def __init__(self): 
     self.obj = lib.Foo_new() 

    def bar(self, num_piezas): 
     lib.Foo_bar(self.obj, num_piezas) 

num_piezas = 5  
f = Foo() 
f.bar(num_piezas) 

的事情是,現在我想發送int陣列,並與數沿着char陣列。所以,我想:

Foo.cpp中

#include <iostream> 
#include <string.h> 

class Foo{ 
    public: 
     void bar(int number, int piezas[3], char prioridades[3][20]){ 
      printf("Number is: %d\n", number); 
      for(int i=0;i<3;i++) { 
       printf("%d", piezas[i]); 
      } 
      for(int q=0;q<3;q++) { 
       printf("%s ", prioridades[q]); 
      } 
     } 
}; 

extern "C" { 
    Foo* Foo_new(){ return new Foo(); } 
    void Foo_bar(Foo* foo, int number, int piezas[3], char prioridades[3][20]){ foo->bar(number, piezas, prioridades); } 
} 

fooWrapper.py

from ctypes import cdll 
lib = cdll.LoadLibrary('./libfoo.so') 

class Foo(object): 
    def __init__(self): 
     self.obj = lib.Foo_new() 

    def bar(self, num_piezas, piezas, prioridades): 
     lib.Foo_bar(self.obj, num_piezas, piezas, prioridades) 

piezas = [1, 2, 3] 
prioridades = ['normal', 'baja', 'primera pieza'] 
num_piezas = 5  
f = Foo() 
f.bar(num_piezas, piezas, prioridades) 

C++文件編譯正確,但是當我嘗試執行Python函數(python fooWrapper.py)此錯誤消息顯示:

Traceback (most recent call last): 
    File "fooWrapper.py", line 15, in <module> 
    f.bar(num_piezas, piezas, prioridades) 
    File "fooWrapper.py", line 9, in bar 
    lib.Foo_bar(self.obj, num_piezas, piezas, prioridades) 
ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>: Don't know how to convert parameter 3 

我做錯了什麼?我需要做其他事情來通過intstring數組作爲參數嗎? 在此先感謝。

回答

1

你需要使用CFUNCTYPE定義一個函數原型(閱讀文檔),然後用新類型包裝你的函數,之後你將得到類型化函數。每次你想使用帶有參數的arg或不同於int的返回類型時,你必須這樣做。

http://docs.python.org/2/library/ctypes.html#function-prototypes

http://docs.python.org/2/library/ctypes.html#callback-functions

Python列表和c陣列是不同的。您可以定義在Python C-數組類型,在這裏閱讀:

http://docs.python.org/2/library/ctypes.html#arrays

5

你可以用這個修改脫身:

from ctypes import c_int, c_char 

... 

# create a 3-int array 
piezas = (c_int*3)() 
piezas[0] = 1 
piezas[1] = 2 
piezas[2] = 3 

# create a 3-(20-char array) array 
prio = ((c_char*20)*3)() 
prio[0].value = "normal" 
prio[1].value = "baja" 
prio[2].value = "primera pieza" 

但既然你與字符數組處理在C++側部分,我建議你改變你的函數定義:void Bar(int num, char* piezas, int len_piezas, char** prio , int len_prio_elem, int prio);。它要長得多,但如果要避免緩衝區溢出,則必須控制輸入數組的長度。

+1

你是對的。我確實提出了一個解決OP問題的快速解決方案,但它最好還是蠻幹的。我會在轉班後寫出適當的解決方案。 – lucasg