在Cython中创建连续数组并将其传递给C ++

时间:2018-07-09 09:32:36

标签: c++ arrays c++11 cython contiguous

编辑:此问题已解决。在计算下面的小示例时,一切都会按预期进行。如果有人发现它有帮助,我将其保留。显然,我的问题出在其他地方。

我正在使用Cython为C ++程序编写Python接口。 C ++程序使用结构的连续数组作为输入。我可以在Cython中创建这些结构的数组或向量,并将其传递给C ++程序。尽管这些容器应该是连续的,但是当C ++遍历它们时(通过增加指向第一个元素的指针),很明显它们不是连续的。打印出结构的字段之一会显示大量垃圾输出。

以Python接口为例:

abc N Refund Maker_Japan_2017_302413 modified date :26/06 10:20
abc N Refund Maker_Japan_2017_Extra  modified date:26/06 10:30
abc N Refund Macker_Italy_2017_302413 modified date :26/06 10:20 
abc N Refund Macker_Italy_2017_xyz modified date :26/06 10:30

然后是一些示例C ++代码。第一个“ program.h”

cdef extern from "program.h" namespace "Thing":
    struct Thing:
        int id
        int data


cdef extern from "program.h" namespace "Thing":
    cdef cppclass Program:
        int attribute_1
        int attribute_2
        void Program(int attr1, int attr2) except +
        void Main(Thing* Things)

cdef class PyProgram:
    cdef Program* c_Program
    def __cinit__(self, int attr1, int attr2):
        self.c_Program = new Program (attr1, attr2)

    cpdef void Main(self, list things):
        cdef vector[Thing] Things # This should be contiguous!
        for t in things:
            Things.push_back(self.make_a_thing(t[0], t[1]))
        self.c_Program.Main(&Things[0], len(Things))

   cdef make_a_thing(self, int id, int data):
       cdef Thing c = Thing(id, data)
       return c

现在是“ program.cpp”

#include <vector>
#include <iostream>
namespace Thing{
struct Thing{
    int id;
    int data;
};

class Program{
public:
     int attr1;
     int attr2;
     Program(int attr1, int attr2): attr1(attr1), attr2(attr2){};
     void Main(Thing* Thing, int size);
};
};    

现在假设我运行以下Python代码

#include "program.h"
#include <iostream>
using namespace Thing;
using namespace std;
void Program::Main(Thing* Things, int size){
    for (int i=0; i<size; ++i){
         cout << (Things+i)->id << endl;
    }
}
int main(){
    return 0;
}

这将按预期打印1,3,5。所以我不知道为什么这个简化的示例可行,但是我的真实程序却吐出了垃圾。我想我会把这个例子留在这里,以防其他人发现它有用,但是此时回答我自己的问题似乎很愚蠢。

1 个答案:

答案 0 :(得分:0)

要更准确地反映我的代码,这是要做的事情。

假设我们对Program的定义如下:

class Program{
public:
    int attr1;
    int attr2;
    Thing* thing;
    Program(int attr1, int attr2, Thing* thing): attr1(attr1), attr2(attr2),      
                                                 thing(thing){};
    void Main(int size);

};

然后在“ program.cpp”中

void Program::Main(int size){
    for (int i=0; i<size; ++i){
         cout << (Things+i)->id << endl;
    }
}

在界面中进行适当的更改后,问题将开始出现。正确的方法是在上面的玩具示例中。我进行了更改,一切正常。

我将其作为答案,这有点倒退,因为此帖子包含错误,而原始帖子包含答案。如果社区认为这是更好的评论,我将对其进行更改。