Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Como puedo ocultar el codigo de una clase en una DLL ?

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Como puedo ocultar el codigo de una clase en una DLL ? Responder citando

Saludos,

Me gustaria ocultar el codigo de los metodos de una clase en una DLL.
Lo que busco es distribuir solamente la cabecera (.h). Es posible ?.
El problema esta al usar la Clase en la aplicacion que hace uso de la DLL.
Que dice que los metodos no sabe donde se encuentran "Unresolved external".

Muchas gracias
Volver arriba
Mensaje    Asunto: Responder citando

La inclusion de codigo en una .dll ( fichero.dll )
no es demasiado seguro, facilitas a la peña
el debugger de la misma.

Mi consejo es si las funciones son
importantes hazlas dentro del propio .cpp
si no, puedas crear una dll.


Aun asi ..., incluso pasando programas
de encriptacion de .exes al final el que sabe
logra abrir todo el codigo.
_________________
Saludos
~~~~~~~~
Wink _Willa
~~~~~~~~
www.avancegame.com
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Cita:
El problema esta al usar la Clase en la aplicacion que hace uso de la DLL


Creamos un archivo de cabecera común a la dll y al ejecutable (miDll.h). En esta cabecera crearemos una clase base abstracta solo con los miembros públicos de nuestra clase final. Como ejemplo usaremos lo siguiente:

Código:
// !!! miDll.h !!!
//--------------------------------------------------------------
#ifndef MidllH
#define MidllH
//--------------------------------------------------------------
#ifdef __DLL__
    #define IMPORT_EXPORT __declspec(dllexport)
#else
    #define IMPORT_EXPORT __declspec(dllimport)
#endif
//--------------------------------------------------------------
class IMiClase
{
public:
    virtual void __stdcall SetA(int valor) = 0;
    virtual void __stdcall SetB(int valor) = 0;
    virtual int __stdcall Suma(void) = 0;
    virtual void __stdcall Liberar(void) = 0;
};
extern "C" IMPORT_EXPORT IMiClase* __stdcall Crear(void);
//--------------------------------------------------------------
#endif


La dll de ejemplo la crearíamos del siguiente modo. Usamos nuestra clase base abstracta, implementamos sus métodos y añadimos los miembros privados que necesitemos e implementamos la función “Crear” que es donde obtendremos un puntero a la nueva instancia de nuestra clase (esto es porque no podemos mezclar el gestor de memoria de la dll con el del ejecutable, o sea, todo los que creemos dentro de la dll lo debemos liberar dentro de la dll).

Código:
// !!! DllMain.h !!!
//--------------------------------------------------------------
#include <windows.h>
#include "midll.h"
//--------------------------------------------------------------
class MiClase : public IMiClase
{
private:
    int a;
    int b;
public:
    void __stdcall SetA(int valor) { a = valor; }
    void __stdcall SetB(int valor) { b = valor; }
    int __stdcall Suma(void) { return a + b; }
    void __stdcall Liberar(void) { delete this; }
};
//--------------------------------------------------------------
IMPORT_EXPORT IMiClase* __stdcall Crear(void)
{
    return new MiClase;
}
//--------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason,
                         void* lpReserved)
{
    return 1;
}
//--------------------------------------------------------------


Y por ultimo para probarla, añadimos el archivo .lib que se ha creado al compilar nuestra dll (suponiendo que queramos enlazar la dll estáticamente):

Código:
// !!! Unit1.cpp !!!
//--------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "midll.h"
#include "Unit1.h"
//--------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//--------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//--------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    IMiClase* MiClase = Crear();
    MiClase->SetA(2);
    MiClase->SetB(3);
    int total = MiClase->Suma();
    ShowMessage(total);
    MiClase->Liberar();
}
//--------------------------------------------------------------


O bien si necesitamos enlazar la dll dinámicamente:

Código:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    typedef IMiClase* (__stdcall* PCrear)(char*);
    HINSTANCE miDll = LoadLibrary("miDll.dll");
    if (miDll)
    {
        PCrear fnCrear = (PCrear)GetProcAddress(miDll, "Crear");
        if (fnCrear)
        {
            IMiClase* MiClase = fnCrear();
            MiClase->SetA(2);
            MiClase->SetB(3);
            int total = MiClase->Suma();
            ShowMessage(total);
            MiClase->Liberar();
        }
        FreeLibrary(miDll);
    }
}


Espero que entiendas el ejemplo aunque este sin comentar, y si no entiendes algo pues aquí estamos…
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias _Leo,

Muy interesante tu respuesta, pero el problema está
en que tengo que heredar de mi clase "oculta" en la aplicación final.
Realmente es una clase que hereda de TForm, de forma que los
forms de mi aplicacion final son descendientes de la clase creada en
la dll.

El problema está en el memory manager... No hay alguna forma
de que DLL y aplicacion usen el mismo gestor de memoria ?

Muchas gracias _Leo, me has ayudado mucho
Volver arriba
Mensaje    Asunto: Responder citando

_Leo he creado un ejemplo basandome en el tuyo, he creado un par de DLLs contiendo clases derivadas basandome en una clase abstracta, luego he creado un programa de prueba, he matenido como tu has hecho la función Crear en el .H de la clase abstracta (vamos casi todo igual).

El caso es que cuando compilo el programa de prueba, obtengo un error Too few parameters in call, en la linea:

Analizador *analiza=fnCrear();

La cual es parte del código:
Código:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   if (RadioButton1->Checked) {
      midll=LoadLibrary("AnalizadorZVRE.dll");
   } else if (RadioButton2->Checked) {
      midll=LoadLibrary("AnalizadorPSP.dll");
   } else {
      ShowMessage("Elige una DLL");
      return;
   }

   if (midll) {
      typedef Analizador* (__stdcall* PCrear)(char*);
      PCrear fnCrear = (PCrear) GetProcAddress(midll, "Crear");
      if (fnCrear) {
         analizador=fnCrear();
      }
   }
}


Donde podría estar el fallo ?

En el .h de la clase abstracta tengo:
extern "C" IMPORT_EXPORT Analizador* __stdcall Crear(void);

Y es implementado en las subclases, devolviendo un puntero al nuevo objeto de la subclase,
AnalizadorZVRE.cpp:
//--------------------------------------------------------------
IMPORT_EXPORT Analizador* __stdcall Crear(void)
{
return new AnalizadorZVRE;
}

AnalizadorPSP.cpp:
//--------------------------------------------------------------
IMPORT_EXPORT Analizador* __stdcall Crear(void)
{
return new AnalizadorPSP;
}

----------------------

Ciao y gracias
Perdonad si posteo en un post antiguo pero creo que es interesante el mensaje.

Post-Data: He probado directamente también tu ejemplo tal cual está y también me dá el mismo error... no sé ya si será fallo mío.

Ciao.
_________________
OJO!! Ya tenemos subforo de Bases de Datos!!
Gracias a los admins.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

Ya he dado con el fallo cuando se define:
typedef IMiClase* (__stdcall* PCrear)(char*);

El parametro debía ser void, debe quedar así:
typedef IMiClase* (__stdcall* PCrear)(void);

Pues en mi ejemplo y en el de _Leo, la función Crear no tiene parámetros.

Ciao
_________________
OJO!! Ya tenemos subforo de Bases de Datos!!
Gracias a los admins.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor MSN Messenger
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.