2015-01-30 2 views
1

이 작업을 수행하는 데 문제가 있습니다. 내가 붙어있는 것은 C++로 작성된 모듈을 임베디드 Python 인터프리터에 노출시키는 것이다.C++ 게임 스크립팅을위한 내장 파이썬 설정

저는 boost :: python을 사용하고 있습니다. 그러나 설명서가 부족한 것처럼 보이기 때문에 내가 이것을 위해 무엇을해야할지 모르겠습니다.

내가 원하는 것은 BOOST_PYTHON_MODULE로 일부 C++ 코드를 노출 한 다음 해당 응용 프로그램에서 에 액세스하는 것입니다. 그러나 나는 그것을 가져올 수 없습니다.

#include <python/interpreter.hpp> 

bp::object blag() { 
    return bp::str("Thingy"); 
} 

BOOST_PYTHON_MODULE(modthingy) { 
    bp::def("blag", &blag); 
} 


Interpreter::Interpreter() { 
    Py_UnbufferedStdioFlag = 1; 
    Py_Initialize(); 
    try { 
     init_module_modthingy(); 
    } catch (bp::error_already_set) { 
     PyErr_Print(); 
    } 

    main_module = bp::import("__main__"); 
    main_namespace = main_module.attr("__dict__"); 
} 

하지만 그건 오류 AttributeError: 'NoneType' object has no attribute '__dict__' 를 인쇄하고 나중에 모듈을 가져올 수 없습니다 : 가장 가까운 (단지 관련 부분)를 보인다 내가있어.

어떻게 구성해야합니까?

편집 : 좋아, 허용 대답의 방법 중 하나 내가 가진 가장 가까운 그래서 : 내가하고 싶은대로

PyImport_AppendInittab("modthingy", &PyInit_modthingy); 
Py_Initialize(); 

그러나,이, 내 경우에 특히 유용하지 않는 것 초기화 기능 후에 모듈을 추가/가져올 수 있어야합니다. 나는 즉, 몇 가지로 볼거야 :

  • 을 내가 파이썬에서 작업 파이썬 2 제안 된 접근 방식을 얻을 수 있다면 내가 잘 모든 명명 요구하는 내 게임을 구성 할 수있는 경우 3
  • 참조하십시오 Py_Initialize 전 모듈

이 게시물을 내 결과와 함께 업데이트 할 예정입니다.

+0

그냥 포기했다고 말하고 싶습니다. 파이썬은 실제로 내가 사용하고자하는 것에 대해 너무 잘 작동하지 않는 것 같습니다. boost.python에 대한 문서는 정말로 오래되었습니다. (비록 지난 12 년 동안 라이브러리가 거의 변경되지 않았기 때문에 믿을 수 있지만) 웹에 거의 모든 예제가 있습니다. 나는 이제 더 많은 전용 스크립팅 언어 인 chaiscript와 angelscript를 조사하고있다. 그들은 내 요구에 더 잘 어울리는 것처럼 보입니다. 편집 :하지만 미래에 python 확장 기능을 작성하기 위해 boost.python을 사용하게 될 것입니다. 이것이 정말 빛나는 곳입니다. – Jagoly

답변

1

Boost.Python은 BOOST_PYTHON_MODULE 매크로를 사용하여 파이썬 모듈 초기화 프로그램을 정의합니다. 결과 함수는 모듈 가져 오기 도구가 아닙니다. 이 차이는 modthingy.py 모듈을 만들고 import modthingy을 호출하는 것과 유사합니다.

모듈을 가져올 때 파이썬은 먼저 모듈이 내장 모듈인지 확인합니다. 모듈이 없으면 Python은 module search path을 검색하여 모듈 이름을 기반으로 파이썬 파일이나 라이브러리를 찾습니다. 라이브러리가 발견되면 파이썬은 라이브러리가 모듈을 초기화 할 함수를 제공 할 것으로 기대합니다. 찾으면 가져 오기가 모듈 테이블에 빈 모듈을 만든 다음 초기화합니다. modthingy과 같이 정적으로 링크 된 모듈의 경우 모듈 검색 경로가 도움이되지 않습니다. 찾을 수있는 라이브러리가 없기 때문입니다.

포함의 경우 module table and initialization function 설명서에 정적 테이블의 경우 초기화 테이블에 항목이 없으면 모듈 초기화 프로그램 함수가 자동으로 호출되지 않는다고 명시되어 있습니다. 인터프리터가 초기화 된 후에

BOOST_PYTHON_MODULE(modthingy) 
{ 
    // ... 
} 

PyImport_AppendInittab("modthingy", &initmodthingy); 
Py_Initialize(); 
// ... 
boost::python::object modthingy = boost::python::import("modthingy"); 

대안 파이썬 2를 들어, 하나의 모듈을 사전에 추가하는 빈 모듈을 작성할 수 파이썬 2 및 Python (3)의 경우, 하나 PyImport_AppendInittab()Py_Initialize() 전에 호출하여이를 달성 할 PyImport_AddModule()을 통해 명시 적으로 모듈을 초기화하십시오.

BOOST_PYTHON_MODULE(modthingy) 
{ 
    // ... 
} 

Py_Initialize(); 
PyImport_AddModule("modythingy"); 
initmodthingy(); 
boost::python::object modthingy = boost::python::import("modthingy"); 

이 접근 방식은 공식적인 Python 임베디드 데모 인 embed/demo.c에 나와 있습니다. BOOST_PYTHON_MODULE에서 만든 모듈 초기화 프로그램은 PyImport_AddModule()을 호출하지 않으므로 명시 적으로 호출해야합니다.

또한 BOOST_PYTHON_MODULE(modthingy) 이처럼, 파이썬 (2)와 (3) 사이의 모듈 초기화 기능 변경된 명명 규칙을 삽입하기위한 파이썬 C의 API는 하나


파이썬 3. 파이썬 2 &PyInit_modthingy위한 &initmodthingy을 사용할 필요가 있으므로주의

#include <iostream> 
#include <string> 

#include <boost/python.hpp> 

std::string spam() { return "Spam spam spam"; } 

BOOST_PYTHON_MODULE(example) 
{ 
    namespace python = boost::python; 
    python::def("spam", &spam); 
} 

int main() 
{ 
    // Add example to built-in. 
    PyImport_AppendInittab("example", &initexample); 

    // Start the interpreter. 
    Py_Initialize(); 

    namespace python = boost::python; 
    try 
    { 
    // >>> import example 
    python::object example = python::import("example"); 
    // >>> x = example.spam() 
    python::object x = example.attr("spam")(); 
    // >>> print x 
    std::cout << "x = " << python::extract<std::string>(x)() << std::endl; 
    } 
    catch (const python::error_already_set&) 
    { 
    PyErr_Print(); 
    } 
} 

출력 :

여기

정적으로 포함 된 통역사와 연결 모듈을 가져 보여주는 최소한의 완벽한 예입니다

x = Spam spam spam 
+0

아름다운! 그것은 트릭을했다. 나는 잘못된 문서를 찾고 있었다고 생각합니다. 내가 설명하는 문서/예제에 대한 링크가 있다고 가정하지 않습니까? 아니면 자신의 경험에서 나온 것입니까? 감사! – Jagoly

+0

@Jagoly 미묘한 세부 사항은 [모듈 테이블 및 초기화 함수] (https://docs.python.org/2/extending/extending.html#the-module-s-method-table-and-initialization)에서 간단히 다룹니다. 기능) 문서화. 관련 자료 및 기능에 대한 링크뿐만 아니라 자세한 내용을 제공하기 위해 답변을 업데이트했습니다. –

+0

흠, AppendInittab 메서드를 작동시킬 수 있지만 AddModule 하나가 더 좋지 않습니다 (초기화 후 모듈을 추가 할 수 있음). 모듈을 가져 오지 만 사용하려고 할 때 속성 블래그가 없다는 메시지 만 표시됩니다. 그냥 빈 모듈처럼 보입니다. PyInit_modthingy는 아무 것도하지 않습니다. 나는 파이썬 3 btw를 사용하고있다. – Jagoly