2016-08-24 4 views
4

C++로 작성된 응용 프로그램과 테스트 시스템 (C++에서도)이 있습니다. 테스트 시스템은 매우 복잡하고 변경하기가 어렵습니다 (저는 약간의 변경 만하고 싶습니다). 내 수업은 다음과 같습니다 :C++에서 python 실행

class Derived : public Base { 
public: 
    void somefunc(const AnotherClass& file) { 
} 
}; 

내부에는 여러 가지 기능이 있습니다. 내 테스트 시스템은 파생 클래스 인스턴스를 만든 다음 몇 가지 작업을 수행하는 메서드를 사용합니다.

이제 파이썬으로 솔루션을 작성하고 싶습니다. 나는 양방향 통합이 필요하다. 내 생각은 somefunc이 호출 될 때마다 실행될 파이썬 함수를 작성하는 것이다. 그리고 저는 파이썬에서 한 함수를 다른 함수로 돌릴 때까지 변수의 값을 잃고 싶지 않습니다. 또한 Python의 Base 클래스 인스턴스에 정의 된 메서드를 사용할 수 있기를 원합니다. 어떻게 이러한 것들을 얻을 수 있습니까?

이러한 용도로 Boost.Python을 선택했습니다. 지금 당장은 C++ 함수를 사용하는 방법, 또는 파이썬에서 간단한 클래스를 사용하는 방법을 이해합니다. 하지만 C++에서 파이썬 함수를 시작하는 방법을 모르겠습니다.

두 번째 질문 - Boost.Python이 좋은 선택입니까? 나는 아주 빠른 것을 필요로하고, 동시에, 사용하기 쉽다.

도움 주셔서 감사합니다.

+1

나는 부스트 파이썬을 해본 적이 있지만, 지금까지 내가 기억하는 당신은 C/C에 포함 파이썬에'#INCLUDE 을'++ 사용할 수 있습니다. 거기에서 꽤 쉽습니다. [여기 링크] (https://docs.python.org/2/extending/embedding.html). 비록 내가 당신이라면 나는 전체 접근법을 다시 생각할 것입니다. 불필요하게 복잡한 작업을하려고하는 것처럼 들리므로 – RoughTomato

답변

3

나는 이런 종류의 일을 위해 Cython을 사용할 것을 권장합니다. another question의 예가 수정되었습니다. (편집가 : 요청에 따라, 나는 C++ 클래스를 랩하는 확장 된 예제를 추가, 더 아래를 참조하십시오.)


편집 : 간단한 예를 들어, 하나의 방법 (C++ -> 파이썬).

quacker.py :

def quack(): 
    print("Quack!") 

cquacker.pyx :

from quacker import quack 

cdef public void cquack(): 
    quack() 

MAIN.CPP :

#if _WIN32 
#include <direct.h> 
#define getcwd _getcwd 
#define PATH_SEPARATOR ';' 
#else 
#include <unistd.h> 
#define PATH_SEPARATOR ':' 
#endif 

#include <iostream> 
#include <string> 
#include <sstream> 

#include <Python.h> 
#include "cquacker.h" 

std::wstring getSysPath() 
{ 
    char cwd[FILENAME_MAX]; 
    getcwd(cwd, FILENAME_MAX); 
    std::wstringstream path; 
    path << Py_GetPath() << PATH_SEPARATOR << cwd; 
    return path.str(); 
} 

int main() 
{ 
    Py_Initialize(); 
    PySys_SetPath(getSysPath().c_str()); 
    PyInit_cquacker(); 
    if (PyErr_Occurred()) 
    { 
    PyErr_Print(); 
    return -1; 
    } 
    cquack(); 
    Py_Finalize(); 
    return 0; 
} 

편집 : 확장 된 예제, 왕복 (C++ -> Python -> C++).

quacker.py :

def qcallback(duck): 
    duck.quack() 

quacker/Duck.hpp

#include <iostream> 

namespace quacker { 

class Duck 
{ 
public: 
    void quack() { std::cout << "Quack!" << "\n"; } 
}; 

} 

cquacker_defs.pxd :

cdef extern from "quacker/Duck.hpp" namespace "quacker": 
    cdef cppclass Duck: 
     Duck() except + 
     void quack() 

cquacker.pyx :

from cython.operator cimport dereference as deref 
from libcpp.memory cimport shared_ptr 

cimport cquacker_defs 

from quacker import qcallback 

cdef class Duck: 
    cdef shared_ptr[cquacker_defs.Duck] _this 

    @staticmethod 
    cdef inline Duck _from_this(shared_ptr[cquacker_defs.Duck] _this): 
     cdef Duck result = Duck.__new__(Duck) 
     result._this = _this 
     return result 

    def __init__(self): 
     self._this.reset(new cquacker_defs.Duck()) 

    def quack(self): 
     assert self._this != NULL 
     deref(self._this).quack() 


cdef public void cqcallback(shared_ptr[cquacker_defs.Duck] duck): 
    qcallback(Duck._from_this(duck)) 

메인.CPP는 :

#if _WIN32 
#include <direct.h> 
#define getcwd _getcwd 
#define PATH_SEPARATOR ';' 
#else 
#include <unistd.h> 
#define PATH_SEPARATOR ':' 
#endif 

#include <iostream> 
#include <memory> 
#include <string> 
#include <sstream> 

#include "quacker/Duck.hpp" 

#include <Python.h> 
#include "cquacker.h" 

std::wstring getSysPath() 
{ 
    char cwd[FILENAME_MAX]; 
    getcwd(cwd, FILENAME_MAX); 
    std::wstringstream path; 
    path << Py_GetPath() << PATH_SEPARATOR << cwd; 
    return path.str(); 
} 

int main() 
{ 
    Py_Initialize(); 
    PySys_SetPath(getSysPath().c_str()); 
    PyInit_cquacker(); 
    if (PyErr_Occurred()) 
    { 
    PyErr_Print(); 
    return -1; 
    } 
    auto duck = std::make_shared<quacker::Duck>(); 
    cqcallback(duck); 
    Py_Finalize(); 
    return 0; 
} 
+0

** boost :: python ** – vz0

+0

@ vz0 : "두 번째 질문 - Boost.Python이 좋은 선택입니까? 매우 빠르고 동시에해야합니다. , 사용하기 쉬운." – kloffy

+0

명확해야 함 : 나는 Boost.Python에 대한 대안으로 질문을 해석했다. Boost에서도 똑같은 일을 할 수 있습니다. 파이썬은 주로 개인적인 취향의 문제입니다. Cython 버전은 빠른 코드를 생성하며 개인적으로는 사용하기가 매우 쉽습니다. – kloffy