0

编辑:这个问题已经解决。在制定下面的小例子时,一切都按预期工作。我留下了它以防有人发现它有帮助。显然,我的问题来自其他地方。

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

作为 Python 接口的示例:

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

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

#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);
};
};    

现在“program.cpp”

#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;
}

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

MyObject = PyProgram(0, 0)
MyObject.Main([(1, 2), (3, 4), (5, 6)])

这将按预期打印 1,3, 5。所以我不知道为什么这个简化的例子有效,但我的真实程序会吐出垃圾。我想我会把这个例子留在这里,以防其他人觉得它有用,但在这一点上回答我自己的问题似乎很愚蠢。

4

1 回答 1

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;
    }
}

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

我把它作为答案,这有点倒退,因为这篇文章包含错误,而原始帖子包含答案。如果社区认为这作为评论更好,我会改变它。

于 2018-07-09T13:34:19.883 回答