Pregunta

Recientemente he estado diseñando una biblioteca de clases Thread, he creado una clase abstracta Thread como la siguiente:

class Thread {
public:
    run() { /*start the thread*/ }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int, void *) = 0;
};

Las clases de subprocesos reales heredarían esta clase abstracta e implementarían el método doOperation en su propia lógica, algo similar a Patrón de estrategia .

El problema es que estoy confiando en una biblioteca de fondo C que define la ejecución del hilo en la siguiente función:

int startThread(char* name, (int)(*)(unsigned int, void*), int, int, int, void*);

Como puedes ver; el segundo parámetro es un puntero de función al bucle del hilo (función principal), y aquí está el problema; Como uso esta función C para iniciar el hilo en el método run, paso la dirección de reinterpret_cast al segundo parámetro, y esto no se puede hacer, debido a la falta de coincidencia de tipos.

He intentado usar <=> para devolver un puntero, pero ISO-C ++ prohíbe devolver un puntero de miembro de función no inicializado. No sé cómo superar este conflicto, ¡supongo que usar un método estático es la única solución, pero explota mi patrón de diseño!

¿Fue útil?

Solución

Primero, asegúrese de leer el enlace que Michael Burr proporcionó, ya que contiene buena información. Entonces, aquí está el pseudocódigo C ++ ish para él:

int wrapperDoOperation(int v, void *ctx)
{
    Thread *thread = (Thread *)ctx;
    return thread->doOperation(v);
}

class Thread {
public:
    run() {
         startThread("bla", wrapperDoOperation, bla, bla, bla, (void *)this);
    }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int) = 0;

friend wrapperDoOperation ......;
};

La idea es que doOperation, siendo una función miembro de Thread, no necesita un contexto nulo *, solo puede guardar lo que pasaría como contexto en el objeto mismo. Por lo tanto, puede usar el puntero vacío para pasar el puntero actual a doOperation. Observe que los detalles nulos * están ocultos para los usuarios de su clase, lo cual es bueno.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top