2

私は cython が初めてで、Python で使用できるように既存の C++ コードを cython でラップしようとしています。私の問題のはるかに単純化されたバージョンは次のとおりです。

ああ

#ifndef A_H
#define A_H
class A
{
public:
    int value;
    A(int x);
    void printA();
};
#endif

A.cpp

#include <iostream>
#include "A.h"
A::A(int x)
{
    std::cout<<"entering A constructor"<<std::endl;
    value = x;
    std::cout<<"exiting A constructor"<<std::endl;

}
void A::printA()
{
    std::cout<<"print value in A :"<<value<<std::endl;
}

cmd.h

#include "A.h"
class CMD
{
public:
    A *a;
    void init(int x);
    void test();

};  

cmd.cpp

#include "cmd.h"
#include <iostream>
void CMD::init(int x)
{
    std::cout<<"start initializing A"<<std::endl;
    a = new A(x); // this line is causing the segmentation fault
    std::cout<<"end initializing A"<<std::endl;
}

void CMD::test()
{
    std::cout<<"start printing A"<<std::endl;
    a->printA();
    std::cout<<"end printing A"<<std::endl;

}

PyCMD.pyx

cdef extern from "cmd.h":
    # cdef cppclass A:
    #     A(int x)
    cdef cppclass CMD:
        # A *a
        CMD()
        void init(int x)
        void test()

cdef class PyCMD:
    cdef CMD *thisptr
    def __cint__(self):
        self.thisptr = new CMD()
    def __dealloc__(self):
        del self.thisptr
    def init(self, x):
        self.thisptr.init(x)
    def test(self):
        self.thisptr.test()

setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
    cmdclass = {'build_ext': build_ext},
    ext_modules = [Extension("cmdtest", ["PyCMD.pyx","cmd.cpp","A.cpp"],language='c++')]
)

ハローワード.py

from cmdtest import *
d = PyCMD()
d.init(10)
d.test()

プログラムはとてもシンプルです。クラス A には、A の値を出力するためのコンストラクターとメソッドしかありません。クラス cmd は、その init() メソッドで A のインスタンスを作成し、test() 内で A の printA() メソッドを呼び出します。cython コードは基本的に、cmd クラスで使用可能なすべてのメソッドを模倣する cdef クラス PyCMD を作成します。helloworld.py を実行すると、出力は次のようになります。

start initializing A
entering A constructor
exiting A constructor
[1]    11689 segmentation fault  {my_python_path}

明らかに、A インスタンスのポインターを割り当てるときにセグメンテーション違反が発生します。次に、main.cpp を作成して、少なくとも C++ コードがしっかりしていることを確認しました。

main.cpp

#include "cmd.h"
int main()
{
    CMD *cmd = new CMD();
    cmd->init(10);
    cmd->test();
}

出力は問題ないようです。

start initializing A
entering A constructor
exiting A constructor
end initializing A
start printing A
print value in A :10
end printing A

問題はcythonにあるはずですが、それがどこにあるのかわかりません。

どんな助けにもとても感謝しています。

4

1 に答える 1

3

問題は、の初期化子がないため、初期化されていないことPyCMDですthisptr

self.thisptrこれは、Cython コードまたはthisC++ コードの任意の場所に出力するだけであることがわかります。

イニシャライザのように見える関数がありますが、の__cint__代わりに呼び出されるため__cinit__、そうではありません。

したがって、同等の C++ コードは次のようになります。

#include "cmd.h"
int main()
{
    CMD *cmd;
    cmd->init(10);
    cmd->test();
}

…これはまったく同じセグメンテーション違反を引き起こします。

于 2013-10-23T20:57:55.833 に答える