2010-06-22 2 views
7

파이썬을 C++로 인터페이스 할 수있는 몇 가지 코드가 있지만 잘 볼 때마다 더 나은 방법이 있어야한다고 생각합니다. C++ 측에는 int, real, string, variant 등의 기본 유형의 고정 된 범위를 처리 할 수있는 'variant'유형이 있습니다. Python API를 사용하여 일부 Python 유형을 변환하는 코드가 있습니다. 다음과 같이 보입니다 :Python C API : PyObject 유형 켜기

variant makeVariant(PyObject* value) 
{ 
    if (PyString_Check(value)) { 
    return PyString_AsString(value); 
    } 
    else if (value == Py_None) { 
    return variant(); 
    } 
    else if (PyBool_Check(value)) { 
    return value == Py_True; 
    } 
    else if (PyInt_Check(value)) { 
    return PyInt_AsLong(value); 
    } 
    else if (PyFloat_Check(value)) { 
    return PyFloat_AsDouble(value); 
    } 
    // ... etc 

문제는 연결된 if-else ifs입니다. switch 문이나 형식 식별자로 키가되는 작성 함수의 테이블이나 맵을 호출하는 것 같습니다. 즉 내가 좋아하는 뭔가를 쓸 수 있도록하려면 : 가장 좋은 방법은 바로 여기에 '유형 ID'를 얻기 위해 무엇인지는 분명 아니었다 API 문서의 탈지를 바탕으로

return createFunMap[typeID(value)](value); 

.

PyTypeObject* type = value->ob_type; 

이 분명히 유형 정보를 빨리 저를 얻을하지만 난에 관심이 유형의 제한된 세트에 관련시키는 것을 사용하는 가장 깨끗한 방법은 무엇입니까 : 나는 이런 식으로 뭔가를 할 수 참조?

답변

3

어쨌든, 나는 당신이 당신 자신의 질문에 대답했다고 생각합니다.

어딘가에있어 데이터를 기반으로 기능을 선택해야합니다. C에서이 작업을 수행하는 방법은 함수 포인터를 사용하는 것입니다.

각 함수에 명확하게 정의 된 인터페이스가있는 object_type-> function mappers의지도를 만듭니다.

variant PyBoolToVariant(PyObject *value) { 
    return value == Py_True; 
} 

Map<PyTypeObject*,variant* (PyObject*)> function_map; 

function_map.add(PyBool, PyBoolToVariant); 

이제 makeVariant는 다음과 같이 표시 될 수 있습니다.

variant makeVariant(PyObject *value) { 
    return (*function_map.get(value->ob_type))(value); 
} 

어려운 부분은 Map 개체의 구문을 올바르게 가져 오게됩니다. 또한, 당신이 타입 매개 변수 (<PyTypeObject*, variant*(PyObject*))를 취할 수있는 Map 객체가 있다고 가정합니다.

아마도지도의 두 번째 유형에 대한 구문을 올바르게 이해하지 못했을 것입니다. 하나의 포인터를 취하여 변형에 대한 포인터를 반환하는 함수에 대한 포인터 여야합니다.

도움이되기를 바랍니다.

+0

감사합니다. function_map.add (PyBool, ... 답변 부분은 API 문서의 올바른 위치를 살펴볼 수있는 힌트로 충분했습니다. PyBool 대신 PyBool_Type이 필요하다고 생각합니다. 제 질문의 핵심은 실제로 내 맵 키로 사용해야했던 PyTypeObject의 * ​​values ​​*는 무엇인가요? – Bob