2013-08-07 22 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