| myevan | http://www.myevan.net | ymir entertainment & eternity |
PyTinker 는 boost::python 에서 나온 LuaBind 가 너무 느려 만들어진 LuaTinker 를 보고 boost::python 을 쓰다 10줄 python 임베딩 루틴을 노트북(참고로 CPU는 1G)에서 컴파일하는데, 백만년 걸리는걸 보고 이틀동안 날밤새서 만든 프로그램입니다.
당연히 boost::python 보다 좋은거는 비스므리한 기능에 컴파일 속도가 빠르다는것 밖에 없으며, 인내력이 남들보다 출중하시거나 컴퓨터 사양이 엄청 좋으신 분들은 그냥 boost::python 을 사용하시는걸 추천합니다.(경험을 같이 한다는 건 참 좋은 일이죠. 특히 괴로운 경험은 더욱이 그렇습니다. 후훗 -_-)y- ~ )
http://www.boost.org/libs/python/doc/
설치해보시고! 멋진 기능을 두루 살펴보시고! 뭔가 다른 생각을 갖게되신다면 다시 아래글을 읽어보시기 바랍니다.
. . . . . .
반갑습니다! boost::python 의 놀라운 성능을 맛보고 오셨군요!!
boost 제작자분들의 멋진 이상은 정말이지 저도 200% 공감합니다. c++ 을 제작하신 분들께도 ... 성함은 잘 모르겠지만.. 어쨌든... 정말 존경의 표시를 다시 한번 밝힙니다.
boost::python 정말 놀라운 라이브러리이며, c++은 정말이지 최고의 언어라고 생각되시지 않으십니까? 저도 boost::python을 쓰기전에는 c++에서 파이썬처럼 작성할 수 있을지는 정말 몰랐습니다.
다만 CPU가 10G정도 되지 않는... 현재 2005년 7월의 무더운 날씨속의현실이 안타까울 따름입니다. 게임에 실제 쓰려면 이부분을 컴파일할때는 밥먹고 편의점가서 음료수 마시면서 노닥거리고 오면 되겠더군요.
아무튼; 이런 연유로 해서 PyTinker 가 탄생하게 되었습니다.
http://www.myevan.net/moniwiki/wiki.php/PyTinker
파일을 받아 압축을 푸시면 아래와 같은 구조를 보실 수 있습니다.
| py_tinker/eternity.dsw | 워크 스페이스 |
| py_tinker/bin/ | 실행 가능한 소스 |
| py_tinker/docs/ | 도움말 |
| py_tinker/include/eter/ | 헤더 파일 |
| py_tinker/lib/ | 라이브러리 |
| py_tinker/src/py_tinker/ | PyTinker 라입 소스 |
| py_tinker/src/py_ex_simple/ | 예제 프로그램 소스 |
| py_tinker/src/py_ex_class/ | 예제 프로그램 소스 |
| py_tinker/extern/python-2.4/include | 외부라이브러리:python-2.4 헤더파일 |
| py_tinker/extern/python-2.4/lib | 외부라이브러리:python-2.4 라입파일 |
Batch Build 를 하시면 아래와 같은 파일들이 생성됩니다.
| y_tinker/lib/py_tinker.lib | PyTinker Release 라입 |
| py_tinker/lib/py_tinker_d.lib | PyTinker Debug 라입 |
헤더 파일은 아래처럼 구성이 되어있습니다.
| py_tinker/include/eter/py_tinker.h | 공개용 헤더 (*) |
| py_tinker/include/eter/__py_tinker_common.h | 내부용 공통 헤더 |
| py_tinker/include/eter/__py_tinker_func.h | 내부용 함수 관련 헤더 |
| py_tinker/include/eter/__py_tinker_method.h | 내부용 메소드 관련 헤더 |
(*) 표된 헤더 외에 다른건 실제 사용할때는 별로 신경쓰실일은 없습니다.
python 은 전역 접근 보다는 모듈을 통한 접근을 하게됩니다. 그래서 임베딩 할때도 module 과 class 단위 객체를 지원합니다.
#include <eter/py_tinker.h>
#include <stdio.h>
const char* text()
{
return "-_-)/ python wins!!";
}
int score(const char* name)
{
printf("[%s] score!! \n", name);
return 100;
}
void initeter()
{
py_tinker::module_("eter")
.deft("text", text)
.deft("score", score)
;
}
void main()
{
Py_Initialize();
Py_SetProgramName((char*)"py_test");
initeter();
py_tinker::PyEmbed_RunMainFile("ex_simple.py");
Py_Finalize();
}
import eter
print dir(eter)
print eter.text()
print eter.score("jaru")
#include <eter/py_tinker.h>
PyTinker 를 사용하기 위한 헤더입니다. 이런식으로 사용하기 위해서는 vc 디렉토리 설정을 해주셔야하며 관련된 내용은 http://www.myevan.net/phpBB/viewtopic.php?t=2341 문서를 참고해주시기 바랍니다.
#include <stdio.h>
printf 를 사용하기 위한 헤더입니다.
const char* text()
{
return "-_-)/ python wins!!";
}
문자열을 리턴하는 함수입니다.
int score(const char* name)
{
printf("[%s] score!! \n", name);
return 100;
}
문자열을 받고, 값을 리턴해주는 함수입니다.
void initeter()
{
위 두 함수를 임포트 하기 위한 모듈("eter")을 만듭니다.
py_tinker::module_("eter")
모듈 이름을 적어줍니다. 모듈이름은 init함수 이름과 동일해야합니다."eter" 모듈이면 initeter() 처럼되어야 합니다.
.deft("text", text)
.deft("score", score)
;
}
출력할 함수 이름과 함수명을 적어줍니다. 이름과 함수명은 달라도 무방합니다. void 리턴함수가 아니기때문에 deft를 사용했습니다. void 리턴함수일 경우에는 defv 를 사용해야합니다. vc 7.0 이상에는 템플릿 확장 기능을 사용해 def 로 하나로 통합할 예정입니다.
void main()
{
메인 프로그램입니다.
Py_Initialize(); Py_SetProgramName((char*)"py_test");
파이썬을 초기화 합니다.
initeter();
"eter" 모듈을 등록합니다.
py_tinker::PyEmbed_RunMainFile("ex_simple.py");
외부 파일을 실행합니다.
Py_Finalize(); }
파이썬을 종료합니다. 다음은 파이썬 소스입니다.
import eter
eter 모듈을 불러옵니다.
print dir(eter)
eter 모듈에 어떤것이 들어있는지 확인합니다.
print eter.text()
text 함수를 호출하고 리턴값을 출력합니다.
print eter.score("jaru")
score 함수에 "jaru"라는 인자를 넣어 호출하고 리턴값을 출력합니다.
['__doc__', '__name__', 'score', 'text'] -_-)/ python wins!! [jaru] score!! 100 Press any key to continue
// py_ex_class.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <eter/py_tinker.h>
#include <stdio.h>
class test
{
public:
void run()
{
puts("hehe -_-)~");
}
int sum(const char* name, int a, int b)
{
printf("%s: %d + %d\n", name, a, b);
return a+b;
}
};
const char* text()
{
return "-_-)/ python wins!!";
}
int score(const char* name)
{
printf("[%s] score!! \n", name);
return 100;
}
py_tinker::class_<test> buildtest()
{
return py_tinker::class_<test>("test")
.defv("run", &test::run)
.deft("sum", &test::sum)
;
}
void initeter()
{
py_tinker::module_("eter")
.deft("text", text)
.deft("score", score)
.def(buildtest())
;
}
void main()
{
Py_Initialize();
Py_SetProgramName((char*)"py_test");
initeter();
py_tinker::PyEmbed_RunMainFile("ex_class.py");
Py_Finalize();
}
import eter
print dir(eter)
print eter.text()
print eter.score("jaru")
inst = eter.test()
inst.run()
print inst.sum("ruzaruza", 1, 2)
처음 소스와 거의 같기때문에 주요 부분만 살펴보도록 하겠습니다.
py_tinker::class_<test> buildtest()
{
깔끔하게 보이기 위해서 별도 함수를 제작합니다. 물론 바로 module_ 에 붙여서 작성하는 방식도 가능합니다.
return py_tinker::class_<test>("test")
클래스를 생성합니다. python용이름은 c++ 클래스명과 달라도 무방합니다.
.defv("run", &test::run)
void 리턴 메소드이기때문에 defv 를 사용합니다.
.deft("sum", &test::sum)
;
}
sum 함수는 다양한 인자가 섞여있지만 큰 문제는 없습니다. void 리턴 메소드가 아니므로 deft 를 사용합니다.
['__doc__', '__name__', 'score', 'test', 'text'] -_-)/ python wins!! [jaru] score!! 100 hehe -_-)~ ruzaruza: 1 + 2 3 Press any key to continue
버그 리포트 및 건의 사항 및 질문 사항은 아래 홈페이지에 글을 남겨주시면 감사하겠습니다.
| 제일 위로 |
| 최종 수정 일시: 07월 24일(2005년) 10:12 PM 편집 | 정보 | 차이 | 비슷한 페이지 DebugInfo |
| 유용한 페이지들: 분류 분류 | 자유로운 연습장 SandBox | 무작위 페이지들 RandomPages | 인기있는 페이지들 MostPopular |