es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Biblioteca dinámica en C++ y puntero void.

Estoy en la siguiente situación: Estoy escribiendo un programa en C++ que debe cargar dinámicamente una biblioteca de C++ (es decir, a través de dlopen y funciones similares en Linux y LoadLibrary y funciones similares en Windows). Esto se puede hacer creando una interfaz en C.

Ahora, tanto en el programa como en la biblioteca, estoy administrando un objeto que tiene algunos miembros de plantilla especificados y algunos métodos:

struct MyObject {
    std::vector<int> _vec;
    //...
    void do_something();
};

Ahora, si la biblioteca se hubiera cargado estáticamente, habría escrito una función de biblioteca como la siguiente:

void some_function(MyObject& o);

Pero como se carga dinámicamente, necesito otra firma. Estaba pensando en lo siguiente: un encabezado común como el siguiente:

//interface.hpp
extern "C" {
    void ob_w(void*);
}


struct MyObject {
   //...
}

Luego, en el lado de la biblioteca:

//lib.cpp
#include "interface.hpp"

void ob_w(void* ptr)
{
    MyObject* p = (MyObject*)ptr;

    p->do_something();
}

y, para el programa principal:

//main.cpp
#include "interface.hpp"

int main()
{
    void* handle = nullptr;
    void (*fptr)(void*);

    handle = dlopen(...)
    fptr = dlsym(...)

    MyObject foo;
    fptr((void*)&foo);

    //...
}

Buscando encontré otras preguntas similares, pero en todas ellas la biblioteca estaba escrita en C y se adoptaron soluciones diferentes. Aquí tanto la biblioteca como el programa están escritos en C++ y el puntero nulo se utiliza solo para evitar algunos adaptadores. Me gustaría saber si mi enfoque es correcto (lo probé en una máquina Linux y parece dar el resultado correcto) y seguro. En caso de que no lo sea, ¿cómo podría pasar el puntero del objeto sin introducir ningún sobrecargo (por ejemplo, un adaptador)?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje de IA, no puedo garantizar la corrección o seguridad de tu enfoque, ya que esto depende de los requisitos específicos y el contexto de tu programa. Sin embargo, tu enfoque de utilizar un archivo de cabecera común y un puntero nulo para pasar la referencia del objeto entre el programa y la biblioteca es una solución común para las bibliotecas C++ cargadas dinámicamente.

    Para evitar cualquier sobrecarga, puedes utilizar una conversión de tipo estática en lugar de una conversión de estilo C al convertir el puntero nulo a tu tipo de objeto en la función de la biblioteca:

    void ob_w(void* ptr)
    {
        MyObject* p = static_cast<myobject*>(ptr);
        p->do_something();
    }
    

    Esto es más seguro que una conversión de estilo C porque realiza una verificación de tipo en tiempo de compilación en lugar de una verificación en tiempo de ejecución, y también es más legible.

    En general, al trabajar con bibliotecas C++ cargadas dinámicamente, es importante asegurarse de que la biblioteca y el programa se construyan con configuraciones de compilador y versiones de biblioteca compatibles para evitar problemas de compatibilidad. También puede ser útil considerar el uso de un archivo de cabecera común y definir una interfaz clara para las funciones de la biblioteca para facilitar el mantenimiento y la actualización del código en el futuro.</myobject*>

Comments are closed.