como quitar el decorado de symbolos en clases exportadas

Iniciado por dewolo, 9 Octubre 2011, 01:41 AM

0 Miembros y 8 Visitantes están viendo este tema.

dewolo

extern "C"
class __declspec(dllexport) Datos
{
public:
         void valorar(int i){val=i;};
private:
         int i;
};

hola estoy tratando de exportar una clase desde una dll para usarla en un programa, lo que qusiera es saber como quito el decoramiento de los exports de la dll ?
ya estuve mirando al respecto http://msdn.microsoft.com/en-us/library/81h27t8c.aspx
pero necesito como quitar el decoramiento de los exports si alguien sabe  :rolleyes:

EI: juntando mensajes.

:-\ no sabia que no se podia
http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx

segun este informe si se exporta una clase usando vc el programa que la va a usar debe ser compilado con el msmo compilador por la gracia del decoramiento de nombres.

EI: juntando mensajes de nuevo.
alguien que sepa puede explicar esto
http://www.codeproject.com/KB/DLL/classesexportedusingLL.aspx

osea la persona esta importando miembros de una clase externa (que esta en una dll), y para encontrar los nombres de los miembros usa getprocaddress pero los nombres no estan decorados como puede ser ?, si habia leido que la decoracion en una clase no se podia evitar (al menos en visual studio), pero esta persona usa visual studio  :-\

otra pregunta seria si puedo usar getprocaddress de la misma forma que uso esta perzona pero pasandole como argumento el nombre decorado ya que decorado o no es un nombre  :P

espero alguna respuesta  ;-)

Eternal Idol

¿Alguna razon para no usar C++ Mature Approach: Using an Abstract Interface?

Y si estan decorados en el hack ese, se lo ve claramente en el output del Dumpbin.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

#2
na si despues mirando bien el autor aclara que uso exports usando .def para desdecorar los decoramientos de esos exports, por eso me llamo la atencion... pero en el dumpbin se ven las funciones decoradas pero abajo se ven sin decorados ....

Citar
EXPORTS
   Add=?Add@CCalc@@QAEHHH@Z
   Sub=?Sub@CCalc@@QAEHHH@Z
   GetLastUsedFunc=?GetLastUsedFunc@CCalc@@QAEPADXZ
   CCalc=??0CCalc@@QAE@XZ



ahora voy a leer sobre esto que lo habia pasado por alto no se que es realmente
C++ Mature Approach: Using an Abstract Interface

sabes que hasta ahora logre que funcione el metodo del hack, pero como yo uso enlazamiento explisito, osea usando loadlibrary y getprocaddress, entonces lo que hice fue usar el nombre decorado como parametro de getprocaddress, se puede tambien  ;D

otra cosa que me gustaria saber es que si yo tengo una DLL y un EXE,  y en los dos proyectos tengo un .h adonde defino una clase, por cierto es la misma clase. y cuando trato de relacionar ambos elementos por ejemplo llamando un export de la DLL en el EXE, y ese export es una funcion que lleva como parametro algo asi "EXPORT void func(Clase c)", y Clase c es un parametro que utliza un objeto de esa clase... osea es compatible no es verdad?
es decir ambos programas van a reconocer que se trata de la misma clase no ?


Eternal Idol

Ya veo, entonces lo que hizo fue un alias con el .DEF ... las direcciones son las mismas pero claro hay que saber el signature de cada una en algun punto (lo pones en el .DEF o en el GetProcAddress pero no te lo podes ahorrar) y este - aunque probablemente no lo haga - puede variar incluso de version en version ...

El hack se puede mejorar ligeramente para no usar assembly:
Código (cpp) [Seleccionar]
typedef void (__thiscall * CCalc_Ctor_ptr) (void*);
CCalc_Ctor_ptr CCalc_Ctor = (CCalc_Ctor_ptr) GetProcAddress (hMod, "CCalc");
...
CCalc_Ctor(pCCalc);


No se entiende muy bien lo ultimo que preguntas (ojo que una DLL no es un programa, es un modulo) pero supongo que la respuesta es si.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

osea que solo poniendo __thiscall como convecnion de llamada ya puedo quitar la parte de asm?
y el thiscall se puede poner explicitametne a partir del visual studio 2005 creo, igual etngo el 2008

lo que te decia es, si tengo un proyecto de una DLL asi, donde EXPORT es para hacer posible que estos symbolos sean exportados

Citar
class EXPORT Datos
{
     /* miembros de clase */
};

EXPORT void FuncionQueUsaUnParametroDeClaseDatos( Datos dat )
{
     /* code */
}

bool DllMain()
{
return true;
}

y despues tengo un EXE asi
Citar
class IMPORT Datos
{
     /* miembros de clase */
};

int WinMain()
{
      Hmod=LoadLibrary("midll.dll");

      Puntero_FuncionQueUsaUnParametroDeClaseDatos = GetProcAddress(Hmod,"FuncionQueUsaUnParametroDeClaseDatos");

       Datos objeto_de_datos

       Puntero_FuncionQueUsaUnParametroDeClaseDatos(objeto_de_datos);

      return 1;
}

si notas que ambos proyectos usan la misma clase es sus codigos, y que el EXE importa una funcion de la DLL, la funcion "FuncionQueUsaUnParametroDeClaseDatos" que usa un parametro que es un objeto de esa clase.....

la pregunta es si ambos codigos cuando se ejecutan reconocen que se trata de la misma clase?, primero eso, y segundo si hace falta hacer que la clase sea EXPORT en la DLL y IMPORT en el EXE, esas son las preguntas  :xD




Eternal Idol

Cita de: dewolo en  9 Octubre 2011, 19:48 PMosea que solo poniendo __thiscall como convecnion de llamada ya puedo quitar la parte de asm?
y el thiscall se puede poner explicitametne a partir del visual studio 2005 creo, igual etngo el 2008

Si, le podes pasar el this explicitamente al constructor y al ser __thiscall lo pone en ecx.

Cita de: dewolo en  9 Octubre 2011, 19:48 PMla pregunta es si ambos codigos cuando se ejecutan reconocen que se trata de la misma clase?, primero eso, y segundo si hace falta hacer que la clase sea EXPORT en la DLL y IMPORT en el EXE, esas son las preguntas  :xD

Me imagino que si aunque seguis teniendo el tema del constructor, podes pasarle &objeto_de_datos supongo. El dllexport lo necesitas para que se exporten los metodos y el dllimport es para cuando usas la libreria de importacion (el .lib).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

#6
Cita de: Eternal Idol en  9 Octubre 2011, 21:06 PM
Si, le podes pasar el this explicitamente al constructor y al ser __thiscall lo pone en ecx.

Me imagino que si aunque seguis teniendo el tema del constructor, podes pasarle &objeto_de_datos supongo. El dllexport lo necesitas para que se exporten los metodos y el dllimport es para cuando usas la libreria de importacion (el .lib).

ahi modifique "FuncionQueUsaUnParametroDeClaseDatos" le agruege el & para que pueda ser modificada en la DLL  :) , osea que el EXE la llama, le pasa el objeto, y se modifica por esta funcion que se importa de la DLL

Citar
class EXPORT Datos
{
     /* miembros de clase */
};

EXPORT void FuncionQueUsaUnParametroDeClaseDatos( Datos &dat )//esta funcion modifica al bojeto
{
     /* modifica el objeto, lo inicializa y le asigna valores a sus miembros (propiedades) */

    dat.setValorA(5);//ejemplo
}

bool DllMain()
{
return true;
}

//--------------

Citar
class IMPORT Datos
{
     /* miembros de clase */
};

int WinMain()
{
      Hmod=LoadLibrary("midll.dll");

      //obtengo la direccion de la funcion en la DLL
      Puntero_FuncionQueUsaUnParametroDeClaseDatos = GetProcAddress(Hmod,"FuncionQueUsaUnParametroDeClaseDatos");

       Datos objeto_de_datos; // creo el objeto de clase en el EXE

       //llamo la funciin para que modifique el objeto
       Puntero_FuncionQueUsaUnParametroDeClaseDatos(objeto_de_datos);

      return 1;
}

pero porqe sigue el problema del constructor? eso lo que no entiendo si en este caso el problema es que ambos codigos usan la misma clase, pero el EXE que importa esa clase no usa ningun miembro, solamente crea un objeto, se lo pasa como parametro a la funcion y esa funcion es la que lo modifica y internamiente ella si llama algunos metodos pero eso se hace en la DLL.

y sobre el IMPORT para la clase en el EXE entonces no es necesario en mi caso no?, o si porque yo hago carga dinamica de esa funcion "FuncionQueUsaUnParametroDeClaseDatos" no necesito .lib ...


Eternal Idol

Cita de: dewolo en  9 Octubre 2011, 22:47 PMahi modifique "FuncionQueUsaUnParametroDeClaseDatos" le agruege el & para que pueda ser modificada en la DLL  :) , osea que el EXE la llama, le pasa el objeto, y se modifica por esta funcion que se importa de la DLL

No dije eso, ahora la pasas por referencia pero el punto era que tenes que llamar al constructor del objeto ... igual que cuando hacias malloc + puntero a funcion para llamarlo, por eso decia de pasarle al constructor &objeto_de_datos.

Cita de: dewolo en  9 Octubre 2011, 22:47 PMpero porqe sigue el problema del constructor? eso lo que no entiendo si en este caso el problema es que ambos codigos usan la misma clase, pero el EXE que importa esa clase no usa ningun miembro, solamente crea un objeto, se lo pasa como parametro a la funcion y esa funcion es la que lo modifica y internamiente ella si llama algunos metodos pero eso se hace en la DLL.

¿Donde esta el codigo del constructor? ¿En la DLL unicamente, no? Bueno ... por eso sigue el problema.

Cita de: dewolo en  9 Octubre 2011, 22:47 PMy sobre el IMPORT para la clase en el EXE entonces no es necesario en mi caso no?, o si porque yo hago carga dinamica de esa funcion "FuncionQueUsaUnParametroDeClaseDatos" no necesito .lib ...

No.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

dewolo

#8
claro esa es mi Confusión porque en el codigo del hack lo que hace es, tiene una DLL y un EXE y en los dos proyectos tiene la misma definicion de la clase con su constructor.... pero como la DLL esta exportando la clase entonces lo que hace en el EXE es crear un bloque de memoria del tamanio de la clase, luego crea un prototypo del constructor y le da la direccion de constructor en la DLL, y mueve a ecx el bloque para que entienda que clase va a usar (va a usarse la del EXE que fue asignada con malloc)

Citar
__asm { MOV ECX, pCCalc }   
pCtor ();

por esto de que el valor se ponia en ecx antes de llamar al constructor o los metodos...

pero en ese ejemplo la persona usa miembros de la clase y su declaracion de la clase que usa en el EXE no contiene las definiciones de los metodos, y eso igualmente no creo que sea la razon, pero a diferencia de mi ejemplo que yo solamente le paso un objeto creado en el EXE y lo tiene que modificar en esa funcion externa "FuncionQueUsaUnParametroDeClaseDatos" que no pertenece a la clase.. entonces porque esa funcion necesita algo mas que el objeto en si ?

tu sugerencia era que haga un constructor asi tanto en el EXE como en la DLL

Datos(Datos *dat)
{
     InicialisacionDeDatos();
     AsignacionDeValores();
}

y que en el WinMain cree el objeto y se lo pase como parametro al constructor recreado este, el cual tube que conseguir dinamicamente. es como que estaria usando la clase de la DLL y ignorando o no usando la del EXE,  :-\

y no seria lo mismo que pasar el objeto a la funcion esa "FuncionQueUsaUnParametroDeClaseDatos"? , que recibe el objeto con el proposito de modificarlo justamente.......

y todavia no entiendo porque el codigo solo esta en la DLL si en el EXE estoy definiendo la clase tambien, yo pensaba que la clase existia en ambos proyectos, cmo puede ser   :-\





Eternal Idol

No nos estamos entendiendo, intenta hacer lo que queres y asegurate de que en algun lado se llame al constructor dela clase para el objeto que creas (con o sin hack) ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón