Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Crear y usar DLLs en C++ Builder 6

Iniciado por josette, 04 de Octubre de 2006, 07:52:58 PM

« anterior - próximo »

josette

Quiero crear una dll en la que tengo definida una clase. Quiero hacelo en builder c++ 6 pero no consiguo hacerlo. Mejor dicho consigo crear la dll pero luego no puedo usar la clase que hay dentro de la dll. me da un error del tipo [Linker error] .....myclase.obj

alguien me hecha una mano??????

LC0

Por casualidad no habrás implementado métodos dentro de la declaración de la clase en el/los ficheros de cabecerca, verdad?

Vamos, cosas como



class C
{
   int a;

   public:
       DLLEXPORT void getA() const { return a; };
};


swapd0

En las dll no puedes tener clases, solo funciones.

Para que el linkador las encuentres tienes que usar el exten "C" antes de cada funcion. Porque con las clases el compilador de C++ cambia los nombres de las funciones miembro (name mangling)

Lo que puedes hacer (yo lo he hecho), es poner una funcion como esta:


#include "MiClase.h"

// devuelve una instancia nueva
extern "C" CMiClase *Instancia();


Asi podras tener una clase dentro de una dll, pero no podras exportar la interface de la clase dentre de la dll, para eso necesitas el COM.

PD: Que raro ver gente que use el C++ Builder, yo me sentia como un bicho raro por usarlo, ademas la gente me decia: ¿C++ Buider..queee? :evil:

sés

:evil: ¡Eh!, que yo uso el Builder... hice el MCM con el ;)
Soy indeciso... ¿o no?

LC0

Citar
En las dll no puedes tener clases, solo funciones.

Discrepo. Es más, hace poco hice una DLL con clases.
Ten en cuenta que una clase es exactamente lo mismo que un struct en C++ (exceptuando la visibilidad por defecto, que en el caso de una clase es privada). Los métodos de la clase son funciones normales y corrientes a las que se le cambia de nombre y se le añade un parámetro más durante la compilación, por lo que pueden ser tratadas perfectamente como funciones no declaradas en clases.


Eso sí, tienes que añadir a la declaración de las funciones (y/o métodos) "__declspec(dllexport)" (lo que más arriba pongo con la macro DLLEXPORT). Eso previene que la llamada a función se haga a una dirección de memoria invariable durante la ejecución. Es decir, que prepara a la llamada para que salte a la dirección de memoria donde, durante la ejecución, se meta la definición de la función.

hotcamus

Sin ver la declaración de la clase y el error exacto es difícil saber cuál es el problema.

Marci

Cita de: "swapd0"
En las dll no puedes tener clases, solo funciones.

Si que se puede meter una clase en una dll pero no se puede crear un objeto desde fuera de la dll (creo que es lo que swapd0 queria decir :) ). Tienes que crear la clase y dentro de la dll añadir una funcion que devuelva una instancia de la misma (tambien una función para borrar el objeto).

LC0

Aún así, puedes crear perfectamente objetos definidos en los include de la biblioteca envasada en DLL, por lo que decía antes.

Eso sí, hablo en el caso de que la DLL se cree a la par que un fichero .lib, para ser enlazada en el momento de carga en memoria del programa. Si cargas la DLL manualmente desde el código, entonces no se, que Dios nos coja confesados xDD.

josette

esto es lo que yo quiero hacer:


my_dll.h
-----------
class __declspec(dllexport) CmyDLL
{
public:
  CmyDLL();

  int create();
};

my_dll.cpp
-----------
DLLEntyPoint()
{
}

__declspec(dllexport) CmyDLL::CmyDLL()
{
}


int __declspec(dllexport) CmyDLL::create()
{
}



Mas o menos esto

y luego hago lo de implib.


game.cpp
-----------
#include "my_dLL.h"

int main ()
{
  CmyDLL game;
}


esto me produce un error de linkado porque dice que no encuentre el .obj

si por ejemplo declaro el cuerpo de los metodos dentro en la definicion de la clase, entonces no me da error.

Hacerse se puede hacer porque yo lo he visto en codigo fuente, pero ya no me acuerdo donde lo vi.

Tal vez sea cosa de configurar algunas opcines en el compilador, pero creo que no tiene mayor misterio.

hotcamus

Creo que el problema es que no estás importando las definiciones en el fichero que usa la dll. Para usar una dll hay dos pasos:

1. Crear la dll, tal y como tú hiciste.
2. Importar la dll en el fichero en el que quieras usarla.

Lo que te falla es el paso 2. Cuando incluyes my_dLL.h en game.cpp, CmyDLL no tiene que tener __declspec(dllexport) sino __declspec(dllimport). Para no tener dos ficheros .h con la misma declaración y diferente atributo se suele usar un truco con macros:


my_DLL.h
----------------------
#ifdef _DLL_CPP_
#define DLL_DECL_SPEC __declspec(dllexport)
#else
#define DLL_DECL_SPEC __declspec(dllimport)
#endif

class DLL_DECL_SPEC CmyDLL { ... };

my_DLL.cpp
----------------------

#define _DLL_CPP_
#include "my_DLL.h"

// .... Resto del fichero sustituyendo __declspec(dllexport) por DLL_DECL_SPEC (aunque creo que no es necesario)


Y game.cpp lo dejas tal y como está. Al incluir my_DLL.h desde game.cpp _DLL_CPP_ no estará definido por lo que DLL_DECL_SPEC será __declspec(dllimport). En cambio, al compilar my_DLL.cpp, DLL_DECL_SPEC será __declspec(dllexport).

Creo que con esto resolverás el problema.

josette

Parece que ya todo va bien. Ademas de incluir el define en el .cpp de la dll
en el proyecto hay que añadir la .lib y ya ta!!!

Gracias a todos!

ethernet

Desde mi punto de vista particular las DLL son un cáncer tremendo para los motores. A todos nos mola eso de cargar dinámicamente código y poder abstraer el render, el sonido, la IA o lo que se te ocurra, pero en mi opinión hay que escapar de eso y mis razones son las siguientes:


- Es rarísimo en caso en que la carga dinámica es requerida. Cuantas veces alguien de los presentes ha usado dos sistemas de render dinámico y lo haya cambiado en tiempo de ejecución?
- Problemas con HEAP, vairbles compartidas, variables static, singletones, news, gestores de memoria y demás
- Problemas a la hora de llevar el control del código y los proyectos. Habitualmente se usan cosas del motor dentro del propio código del módulo, por ejemplo de render, y si no lo haces muy bien terminarás compilando dos veces el mismo código.

Por estas razones yo desaconsejo el uso de DLL. Los únicos casos que considero interesantes es para pluggins o para librerías muy concretas, pero nada más.

alvarogili

Cita de: "josette"Parece que ya todo va bien. Ademas de incluir el define en el .cpp de la dll
en el proyecto hay que añadir la .lib y ya ta!!!

Gracias a todos!


yo tengo una consultita...como levanto desde cualquier programa echo en borland c++ una dll? gracias de antemano...






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.