7

私は Python を C++ に接続するためのコードをいくつか持っていますが、これは正常に動作しますが、それを見るたびに、それを行うためのより良い方法があるに違いないと思います。C++ 側には、固定範囲の基本型 (int、real、string、バリアントのベクトルなど) を処理できる「バリアント」型があります。Python API を使用して、同等の Python 型から変換するコードがいくつかあります。次のようになります。

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 if です。switch ステートメント、または型識別子をキーとする作成関数のテーブルまたはマップを呼び出しているようです。言い換えれば、私は次のようなものを書くことができるようにしたい:

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

API ドキュメントの概要に基づいて、ここで「typeID」を直接取得する最善の方法は明らかではありませんでした。私はこのようなことができると思います:

  PyTypeObject* type = value->ob_type;

これにより、タイプ情報がすぐに得られるようですが、それを使用して、関心のある限られたタイプのセットに関連付ける最もクリーンな方法は何ですか?

4

1 に答える 1

3

ある意味で、あなたはあなた自身の質問に答えたと思います。

どこかで、データに基づいて機能を選択する必要があります。C でこれを行う方法は、関数ポインターを使用することです。

object_type->function マッパーのマップを作成します... 各関数には明確に定義されたインターフェイスがあります。

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 オブジェクトの構文を正しくすることです。また、型パラメーター ( ) を使用できる Map オブジェクトがあると想定しています<PyTypeObject*, variant*(PyObject*)

おそらく、2 番目のタイプの Map の正しい構文を完全には理解していません。これは、1 つのポインターを取り、バリアントへのポインターを返す関数へのポインターである必要があります。

これがお役に立てば幸いです。

于 2010-06-22T12:26:18.233 に答える