• Lunes 18 de Noviembre de 2024, 05:40

Autor Tema:  Dll Creada En Visual C++ No Funciona En Vb  (Leído 3199 veces)

DrakerDG

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
    • http://drakerdg.xbot.es/wordpress/
Dll Creada En Visual C++ No Funciona En Vb
« en: Lunes 29 de Agosto de 2005, 11:44 »
0
Soy principiante en programación en Visual C++,  por lo que me cuesta un poco entender, revise en el foro discusiones similares y que se puediera compilar mi proyecto y luego crear la dll, pero al intentar llamar la funcion de la dll desde visual basic me da el siguiente error:

Can´t find DLL entry point GetCharX in LCDse

Especificando la dll creada se llama LCDse y la funcion GetCharX.

Los archivos en visual C++ utilizados son los siguientes:

LCDse.h:

#define EXPORT __declspec( dllexport )

EXPORT char *GetCharX(int, int);

y el LCDse.cpp:

#include <windows.h>
#include "LCDse.h"

EXPORT char *GetCharX(int iCode, int bPage)
{
char sTheCode[40];
strcpy(sTheCode, "0000000000000000000000000000000000000000");

switch (iCode)
{
case 1: strcpy(sTheCode, "0000001110110111000111111011100000000000");
break;
case 2: strcpy(sTheCode, "0000001110101011111110001011100000000000");
break;
case 3: strcpy(sTheCode, "0000001010111111111101110001000000000000");
break;
case 4: strcpy(sTheCode, "0000000100011101111101110001000000000000");
break;
case 5: strcpy(sTheCode, "0111001110111111111101010001000111000000");
break;
case 6: strcpy(sTheCode, "0010001110111111111101010001000111000000");
break;
case 7: strcpy(sTheCode, "0000000000011100111001110000000000000000");
break;
case 8: strcpy(sTheCode, "1111111111100011000110001111111111100000");
break;
case 9: strcpy(sTheCode, "0000001110100011000110001011100000000000");
break;
case 10: strcpy(sTheCode, "1111110001011100111001110100011111100000");
break;
}
return sTheCode;
}

Disculpen las molestias, y les agradezco de antemano su ayuda.  :)
Saludos desde Guatemala, C. A.
Electrobotics

Diodo

  • Moderador
  • ******
  • Mensajes: 658
    • Ver Perfil
    • http://www.solocodigo.com
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #1 en: Lunes 29 de Agosto de 2005, 12:07 »
0
Hola

Nunca he usado dlls de visualc++ en visual basic, asi que no se muy bien que puede suceder.Aunque tiene pinta de que no encuentre el .h verifica la ruta de acceso a la libreria, o ponla en el mismo directorio del proyecto

Aca tienes un ejemplo de creacion de una dll en visual c++ y su uso en visual basic

http://alonso_m.tripod.com/visualc/creardll.htm

Espero que te sirva

salu2  :hola:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #2 en: Lunes 29 de Agosto de 2005, 12:11 »
0
El problema es el que marca VB, no encuentra la funcion GetCharX exportada en la libreria. Esto pasa porque la estas exportando como C++: ?GetCharX@@YAPADHH@Z.

La tenes que exportar como C y stdcall para que no te decore el nombre y VB la pueda usar (VB no soporta otra convencion de llamada que no sea stdcall).

En el .H:

extern "C" EXPORT char * __stdcall GetCharX(int, int);

En el .CPP:

extern "C" EXPORT char * __stdcall GetCharX(int iCode, int bPage)

De cualquier manera tampoco esta correcto el codigo, estas devolviendo un puntero a una variable local y estas variables estan en la pila, tenes un par de opciones pero la mas facil es que pongas sTheCode fuera de la funcion.

 :smartass:  :devil:

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

DrakerDG

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
    • http://drakerdg.xbot.es/wordpress/
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #3 en: Martes 30 de Agosto de 2005, 07:28 »
0
Gracias Diodo y Etereal Idol  :comp:
Después de varias horas, investigando, probando lo sugerido y modificando la función un poco logre el desempeño esperado.
Para hacer efectiva la retro-alimentación, escribo lo que realice, paso a paso:

1.   Abrí un nuevo (New) proyecto (projects) en Visual C++ seleccionando el tipo MFC AppWizard (dll).  En el cuatro de texto del nombre (Project name), escribí el nombre de LCDx (El nombre de la librería a crear).  Después de hacer clic en aceptar (Ok) Visual C++ despliega un cuadro en el cual hay que seleccionar que tipo de librería quiere uno crear, para este caso se escoge la primera opción (Regular DLL with MFC statically linked).  Al presionar finalizar (finish) se visualiza un cuadro en el cual aparece la información del nuevo proyecto a crear (New Project Information), clic en aceptar (Ok) y listo.

2.   Visual C++ genera varios archivos necesarios en distintas carpetas (Source Files, Header Files, Resource Files y External Dependencias).  En la primer carpeta deben aparecer los siguientes archivos:  LCDx.cpp, LCDx.def, LCDx.rc y StdAfx.cpp.  En la segunda tenemos:  LCDx.h, Resource.h y StdAfx.h.  En las carpetas restantes aparecen otros archivos que no menciono pues no fueron modificados.

3.   Abrí el archivo LCDx.cpp en el cual pegue mi función (modificada) después de la ultima instrucción que empieza con # (#endif).  La función pegada es la siguiente:

extern "C"
int WINAPI GetCharX(int iCode, int bPage, char* sBits)
{
   char *sCBits;
   char sTheCode[40];
   strcpy(sTheCode, "0000000000000000000000000000000000000000");

   switch (iCode)
   {
   case 1: strcpy(sTheCode, "0000001110110111000111111011100000000000");   
      break;
   case 2: strcpy(sTheCode, "0000001110101011111110001011100000000000");   
      break;
   case 3: strcpy(sTheCode, "0000001010111111111101110001000000000000");   
      break;
   case 4: strcpy(sTheCode, "0000000100011101111101110001000000000000");   
      break;
   case 5: strcpy(sTheCode, "0111001110111111111101010001000111000000");   
      break;
   case 6: strcpy(sTheCode, "0010001110111111111101010001000111000000");   
      break;
   case 7: strcpy(sTheCode, "0000000000011100111001110000000000000000");   
      break;
   case 8: strcpy(sTheCode, "1111111111100011000110001111111111100000");   
      break;
   case 9: strcpy(sTheCode, "0000001110100011000110001011100000000000");   
      break;
   case 10: strcpy(sTheCode, "1111110001011100111001110100011111100000");   
      break;
   }

   sCBits=sBits;
    for (int n=0; n<40; n++)
    {
      *sCBits=sTheCode[n];
       sCBits++;
    };

    return (bPage);
}

Nota:  Esta función recibe 3 parámetros de los cuales los dos primeros son enteros y él ultimo es un char pero por referencia.   Dependiendo del numero recibido asigna un juego de caracteres por medio del switch case a la variable tipo carácter por medio de un puntero.  La versión anterior asignaba estos caracteres a la función como puntero, pero me imagino que por estar en una DLL, aún estando fuera de la función, la variable puntero perdía el valor y la función en la DLL fallaba.  Por esta razón modifique los parámetros a esta forma.

Continua en el siguiente post...... :comp:
Saludos desde Guatemala, C. A.
Electrobotics

DrakerDG

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
    • http://drakerdg.xbot.es/wordpress/
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #4 en: Martes 30 de Agosto de 2005, 07:31 »
0
---------------------------------------------------------------
*******  Continuación del anterior post *******
---------------------------------------------------------------
 :comp:

4.   En el archivo LCDx.h pegue el encabezado de la misma función justo arriba de la ultima línea de slash (////////////////////////) del código que automáticamente Visual C++ escribe en este archivo, de la siguiente manera:

#ifdef __cplusplus
extern "C" {
#endif
 
int WINAPI GetCharX(int, int, char*);
 
#ifdef __cplusplus
}
#endif


5.   Para que esta función pudiera ser acezada desde visual basic, en el archivo LCDx.def escribí justo por debajo de la palabra EXPORTS el nombre de la función quedando escrita como sigue:

; LCDx.def : Declares the module parameters for the DLL.

LIBRARY      "LCDx"
DESCRIPTION  'LCDx Windows Dynamic Link Library'

EXPORTS
   GetCharX

Nota:  Solo escribí el nombre de la función “GetCharX”, lo demás ya estaba escrito.

6.   Por ultimo el proceso de compilación.  El cual realicé con los archivos de la carpeta Source files de extensión “cpp”.  El primero en compilar fue el de nombre StdAfx.cpp (Ctrl+F7 o la primera opción “Compile LCDx.cpp” del menú Build), dicho paso fue necesario para que el siguiente archivo se pudiera compilar.  Paso siguiente, compile (Ctrl+F7 o ...) el archivo LCDx.cpp, y por ultimo inicié el proceso de construcción de la librería LCDx.dll presionando F7 o la segunda opción “build LCDx.dll” del menú build.  Esta ultima acción generó el archivo en la carpeta debut que se encuentra en la carpeta donde se salvé el proyecto completo.  Esta librería la copie en la carpeta del sistema (system) de Windows.

Como parte adicional (Anexo), escribo la sintaxis con la cual se declara la función en un proyecto de visual basic.  Esta se escribe en el cuerpo de un modulo (archivos .mod, por ejemplo:  recurso.mod) de la siguiente manera:

Declare Function GetCharX Lib "LCDx" (ByVal xCodigo As Long, _
                                      ByVal xPagina As Long, _
                                      ByVal sCodigo As String) As Long

Luego se puede generar una función un poco más simple para obtener cada valor en uno de los formularios del proyecto pudiendo ser de esta manera:

Public Function funcCodigo(ByVal xNumero As integer, _
                           ByVal xPagina As integer) As String
Dim iValor As Long
Dim sCodigo As String
sCodigo = Space(40)   'Inicializa el valor del string a 40 espacios en blanco.
iValor = GetCharX(xNumero, xPagina, sCodigo)
funcCodigo = sCodigo  

End Function


Al llamar la función resulta:

Print funcCodigo(2, 1)

Se imprime (en este caso sobre el formulario) lo siguiente:

0000001110101011111110001011100000000000

 :ph34r: Puede parecer un poco aburrido para los que tienen la habilidad y conocimiento sobre estos lenguajes, pero sé que puede ser de mucha utilidad para alguien, como en mi caso empieza a conocerlos  :blink: .

Gracias nuevamente.  :D
Saludos desde Guatemala, C. A.
Electrobotics

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #5 en: Martes 30 de Agosto de 2005, 07:41 »
0
Era mucho mas simple como venias haciendolo (sin archivo de definiciones). Por cierto WINAPI es una macro que esta definida jutsamente a __stdcall, con lo cual pusiste lo que te dije extern "C" y __stdcall pero sacaste algo que ya usabas antes (dllexport).

 :smartass:  :devil:

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

DrakerDG

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
    • http://drakerdg.xbot.es/wordpress/
Re: Dll Creada En Visual C++ No Funciona En Vb
« Respuesta #6 en: Martes 30 de Agosto de 2005, 09:05 »
0
:hola: Gracias por la explicación sobre el macro WINAPI, realmente solo lo copie de un ejemplo que realicé en base a un link que indicó Diodo (http://alonso_m.tripod.com/visualc/creardll.htm.

Por cierto fue el primero que probé hacer pero no me funcionó, en realidad le encontré unos errores, pero no estoy completamente seguro.  Lo que sí sé es que al modificarlos, una de las funciones empezó a funcionar.

Código sin modificar en el archivo Demo.cpp:

void WINAPI LlenaDeX(char* cadena, int largo)
{
   char *puntero;
   puntero=cadena;
   for (int n=1;n=largo;n++)
   {
      *puntero='X';
      puntero++;
   };
};

Código modificado:

void WINAPI LlenaDeX(char* cadena, int largo)
{
   char *puntero;
   puntero=cadena;
   for (int n=0;n<largo;n++)
   {
      *puntero='X';
      puntero++;
   };
};

Cuando intente hacer funcionar esta función (con el código sin modificar), se trabaja la aplicación de visual basic (loop infinito), tenia que cerrarla a la fuerza.

 :hola: Me voy a descansar, hasta luego :blink: .
Saludos desde Guatemala, C. A.
Electrobotics