Domanda

Ho qualche codice per interfacciarsi Python a C ++ che funziona bene, ma ogni volta che lo guardo penso che ci deve essere un modo migliore per farlo. Sul lato C ++ c'è un tipo 'variante' in grado di affrontare una serie fissa di tipi fondamentali - int, reali, stringhe, vettore di varianti, ecc ho qualche codice utilizzando l'API Python per convertire dai tipi Python equivalenti. Sembra qualcosa di simile a questo:

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

Il problema è la incatenato if-else if. Sembra essere chiamata fuori di un'istruzione switch, o una tabella o una mappa delle funzioni di creazione che viene digitato da un identificatore di tipo. In altre parole, voglio essere in grado di scrivere qualcosa di simile:

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

In base a un magro della documentazione API non era evidente ciò che il modo migliore è quello di ottenere il 'TypeId' qui direttamente. Vedo che posso fare qualcosa di simile:

  PyTypeObject* type = value->ob_type;

Questo mi viene apparentemente rapidamente le informazioni sul tipo, ma qual è il modo più pulito per l'uso che per riguardare l'insieme limitato di tipi Sono interessato a?

È stato utile?

Soluzione

In un certo senso, penso di aver risposto alla tua domanda.

Da qualche parte, si sta andando ad avere per selezionare la funzionalità sulla base di dati. Il modo per farlo in C è quello di utilizzare puntatori a funzione.

Crea una mappa di mapper object_type-> funzione ... dove ogni funzione ha un'interfaccia ben definito.

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

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

function_map.add(PyBool, PyBoolToVariant);

Ora il vostro makeVariant può assomigliare a questo.

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

La parte difficile sta per essere ottenere il giusto sintassi per l'oggetto Map. Inoltre, sto supponendo che non v'è un oggetto Map è possibile utilizzare che prende parametri di tipo (<PyTypeObject*, variant*(PyObject*)).

I probabilmente non del tutto ottenuto la sintassi corretta per il secondo tipo di mappa. Dovrebbe essere un puntatore ad una funzione che prende un puntatore e restituisce un puntatore a una variante.

Spero che questo sia utile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top