사용자 도구

사이트 도구


research:embeddedpython

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
research:embeddedpython [2014/01/27 01:00] – [두번째 boost.python 예제] changwooresearch:embeddedpython [2014/10/09 21:24] (현재) – 바깥 편집 127.0.0.1
줄 127: 줄 127:
  
 === C의 데이터를 파이썬의 객체형으로 표현 === === C의 데이터를 파이썬의 객체형으로 표현 ===
-우선 C의 데이터를 파이썬의 객체형으로 표현하는 법에 대해 설명합니다. C에서 파이썬의 문자열을 생성하는 함수는 [[http://docs.python.org/2/c-api/string.html#PyString_FromString|PyString_FromString()]]입니다. 리턴 형은 ''PyObject*''인데 모든 파이썬의 데이터는 이 ''PyObject''입니다. 파이썬의 어떤 자료형이라도 PyObject로 표현되므로, 항상 주의하여야 합니다.+우선 C의 데이터를 파이썬의 객체형으로 표현하는 법에 대해 설명합니다. C에서 파이썬의 문자열을 생성하는 함수는 [[http://docs.python.org/2/c-api/string.html#PyString_FromString|PyString_FromString()]]입니다. 리턴 형은 ''PyObject*''인데 모든 파이썬의 데이터는 이 ''PyObject''입니다. 파이썬의 어떤 자료형이라도 ''PyObject''로 표현되므로, 항상 주의하여야 합니다.
 <code C> <code C>
   char *str = NULL;   char *str = NULL;
줄 481: 줄 481:
  
 <code cpp call.cpp> <code cpp call.cpp>
-#include <boost/python/import.hpp> 
-#include <boost/python/extract.hpp> 
 #include <iostream> #include <iostream>
-#include <string>+#include <boost/python.hpp>
  
-using namespace boost::python;+namespace bp = boost::python; 
 + 
 +void workaround_for_local_modules() 
 +
 + PyRun_SimpleString( 
 + "import sys\n" 
 + "sys.path.append('.')\n"); 
 +}
  
 int main(int argc, char** argv) int main(int argc, char** argv)
 { {
- if(argc < 3) { +    if (argc < 3) { 
- std::cerr << "Usage: call.out pythonfile function val1 val2\n"; +        fprintf(stderr,"Usage: call pythonfile funcname [args]\n")
- return 1; +        return 1; 
-+    
- +
  Py_Initialize();  Py_Initialize();
 + workaround_for_local_modules();
  
- object sys import("sys"); + try { 
- sys.attr("path").attr("insert")(0, "");+ bp::object module_name; 
 + bp::object module; 
 + bp::object func; 
 + 
 + module_name bp::object(bp::handle<>(PyString_FromString(argv[1]))); 
 + module = bp::object(bp::handle<>(PyImport_Import(module_name.ptr()))); 
 + func = module.attr(argv[2])
 + 
 + if(func && PyCallable_Check(func.ptr())) { 
 + bp::object tuple; 
 + 
 + tuple = bp::object(bp::handle<>(PyTuple_New(argc - 3))); 
 + for(int i = 0; i < argc - 3; ++i) { 
 + PyObject* arg; 
 + arg = PyInt_FromLong(atoi(argv[i+3])); 
 + PyTuple_SetItem(tuple.ptr()i, arg); 
 +
 + 
 + bp::object valueObj; 
 + int value; 
 +  
 + valueObj = bp::object(bp::handle<>(PyObject_CallObject(func.ptr(), tuple.ptr()))); 
 + value = bp::extract<int>(valueObj); 
 + 
 + std::cout << value << std::endl; 
 +
 + 
 + } catch(bp::error_already_set const &) { 
 + PyErr_Print(); 
 + }
   
- object module = import(argv[1]); 
- object func = module.attr(argv[2]); 
-  
- int r = extract<int>(func(atoi(argv[3]), atoi(argv[4]))); 
- std::cout << r << std::endl; 
  Py_Finalize();  Py_Finalize();
 + return EXIT_SUCCESS;
 } }
 </code> </code>
 +
 +''PyObject''가 ''boost::python::object''로 래핑되어 있습니다. 또한 ''boost::python::handle<>''을 이용하면 ''PyObject''의 레퍼런스를 관리해 줍니다. ''boost::python''의 대부분의 기능은 extending에 초점이 맞춰져 있고 embedding에는 그다지 많은 기능을 제공하지 않는 편이므로 상당히 많은 부분에서 C API를 그대로 가져와 사용해야 합니다.
  
  
research/embeddedpython.1390784457.txt.gz · 마지막으로 수정됨: 2014/10/09 21:23 (바깥 편집)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki