C/Visual C - DLL creade en VC++ da error en VBasic

 
Vista:

DLL creade en VC++ da error en VBasic

Publicado por Draker (2 intervenciones) el 29/08/2005 09:29:35
Soy novato en la cración de libreriad dinámicas en C, encontré información en el help y en la web, pero admito que me cuesta entender algunos puntos. A pesar de todo lobré realizar la librería, se complilo y se creo la libreria ya con extensión dll (LCDse.dll)

La decraro en Visual Basic, como cualquier funcion del API (por ejemplo), pero cuando llamo a la unica función de la misma (GetCharX), me da el siguiente error:

Can't find DLL entry point GetCharX in LCDse.

Entiendo que no encuentra el punto de entrada en la dll, pero realmente no se donde cometí el error al crear la dll.

Para referencia pego a continuacion los dos archivos que genere en Visual C++

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;
}

No se si ustedes saben donde puedo encontrar información al respecto (manuales y o ejemplos) . Para así poder entender sobre como crear librerias dinamicas en Visual C++, y como crear funciones similares a la que intenté crear. Gracias de antemano
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:DLL creade en VC++ da error en VBasic

Publicado por Mr. Sade (40 intervenciones) el 29/08/2005 12:09:13
crea un archivo def y escribes
LIBRARY nombredetudll
EXPORTS
GetCharX

y otra cosa vb solo soporta __stdcall
char* __stdcall GetCharX(int, int);

y para terminar sTheCode es una variable local y sera destruida al salir de la funcion lo que hara que retornes un puntero invalido.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:DLL creade en VC++ da error en VBasic

Publicado por Draker (2 intervenciones) el 30/08/2005 06:44:00
Gracias Mr. Sade:
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 y para que si alguna otra persona le sirve, 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.

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

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.

Gracias nuevamente.

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar