ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • pyd 파일 없이 c++과 python 연동하기
    프로그래밍/c++ 2015. 11. 20. 05:44
    반응형

    pyd 파일 만들지 않고 c++과 Python 연동하기


     

    서버 코드에 일부 변동될 있는 부분들을 스크립트로 빼고 싶었다.

    유저 accept 포트, 최대 유저 , 인스턴스 등등.. 부터,

    특정 상황마다 콜백이 불려서 뭔가를 체크하는 간단한 행동 정도면 오케이.

    그리고 석찬이 형이 테스트 부분을 스크립트로 빼면, 형도 부담 없이 이런저런 수치를 바꿔보며 테스트를 수도 있고, 나는 다른 작업을 있으니까 편할 것이다.

    고작 졸업 프로젝트 정도인데? 라고도 생각할 사람도 있겠지만, 다른 스킬들을 익혀봐야 나쁠 없으니까

    여튼, 단순히 변수의 값을 설정하는 정도라면 텍스트 파일 정도로만 빼도 상관이 없었지만 약간의 처리 로직까지 첨부가 되어야한다면 텍스트 파일 정도로는 부족한 걸 사실이다.

    과거 내가 기획자 과정을 들었을 , 스크립트 언어를 써보고 싶었지만 됐었던 때의 아쉬움이 생각나서도 조금 있었고. -.-ㅋㅋ

    여튼, 주말에 파이썬을 조금 봤었는데, 거기서 말하는 파이썬은 (Glue!) 언어!라는 말이 인상깊었다. 

    그럼 이번 프로젝트에 붙여보면 어떨까 -_-ㅋㅋ; 하는 생각이 .

    마침 boost python과의 연동을 돕는 라이브러리가 있다길래 boost::python으로 알아봤다.

     

    --- 여기서부터가 본문

     

    가장 먼저 찾았던 대략적인 내용들은, 클래스를 래핑해 pyd 파일을 만들고 연동하는 방식이었다.

    여기서 pyd 파일은 dll 파일 같은 것이다.


    BOOST_PYTHON_MODULE(ModuleName)
    {
        //…기존의 클래스를 래핑
    }


    자세한 내용은 네이버에서 검색해도 많이 나오니 찾아보면 될 듯.

    흠, 아주 작은 부분들만 처리하고 싶었는데 뭔가 그냥 까다롭다고 느낌

    매번 저렇게 pyd 파일을 만들어야하나?

    곧바로 연동할 있으면 좋겠는데.. 다른 방식이 있지 않을까 해서 찾아봤다.

    그냥 구글에서 boost python쓰고 뜨는 모든 페이지를 파봄. -_-;;

     

    그리고 이런 샘플 코드를 발견했다

    음 뭐라고 써놓은 건진 잘 모르겠지만, 뭔가 내가 원하던 방식 같은걸? 하는 생각이 딱 드는 코드였다. 코드는 비슷비슷한 부분이 많으니까 그냥 그렇게 생각했다.

    대략 이런 내용..


    namespace py = boost::python;

    // 스크립트 파일 임포트
    py::object script = py::import("game_server_script");

    // 스크립트 파일의 전역 사전을 가져옴
    py::object main_namespace = script.attr("__dict__");

    CppClass cpp;

    // CppClass를 바인드
    main_namespace["CppClass"] =
        py::class_<CppClass>("CppClass")
        // 바인드할 함수
        .def("getNum", &CppClass::getNum)
        .def("setNum", &CppClass::setNum);

    // 스크립트 파일의 on_init 함수 실행
    script.attr("on_init")();

     

    테스트를 해보니 문제 없이 돌아간다. 주석은 생각대로 달았음 대충 이런 느낌으로 이해하면 되겠구나 해서

    주석은 실제와는 다르거나, 틀릴 수도 있다.

    별도의 모듈을 만들지 않아도 되니까 편함 내가 생각했던 언어를 쓰는 느낌이다.

     

    부분만 있으면 이걸 어떻게 합쳐서 쓰면 되는거야 T__T 하는 생각이 들었던 적이 있어서.. 샘플코드의 풀버전을 올림


    using namespace std;
    using namespace boost;
     
    #include <boost/python.hpp>
     
    namespace py = boost::python;
     
    class CppClass
    {
    public:
     
      int getNum()
      {
        cout << val_ << endl;
        return val_;
      }
     
      void setNum(int newVal)
      {
        val_ = newVal;
      }
     
    private:
     
      int val_ = 0;
    };
     
    int main()
    {
      Py_Initialize();
      
      try
      {
        namespace py = boost::python;
     
        // 스크립트 파일 임포트
        py::object script = py::import("game_server_script");
     
        // 스크립트 파일의 전역 사전을 가져옴
        py::object main_namespace = script.attr("__dict__");
     
        CppClass cpp;
     
        // CppClass를 바인드
        main_namespace["CppClass"] =
          py::class_<CppClass>("CppClass")
          // 바인드할 함수
          .def("getNum", &CppClass::getNum)
          .def("setNum", &CppClass::setNum);
     
        // 스크립트 파일의 on_init 함수 실행
        script.attr("on_init")();
      }
      catch (const py::error_already_set& pyerr)
      {
        PyErr_Print();
      }
     
      Py_Finalize();
     
      return 0;
    }


    -- 여기까지  2015 11 20일 금요일 오전 5:07 (새벽!! )

    반응형
Designed by Tistory.