Foro de elhacker.net

Programación => Programación General => Mensaje iniciado por: erikcmauricio en 6 Diciembre 2017, 22:24 pm



Título: Problema Dll C++ DevC++ y Visual Basic 6
Publicado por: erikcmauricio en 6 Diciembre 2017, 22:24 pm
Buenas tardes gente....

Necesito pasar una cadena de texto de Visual Basic 6 a una Dll de DevC++ y mostrar un mensaje de la DLL

Tengo entendido que VB6 usa Unicode y DevC++ Ansi.... y no encuentro como convertirlo....

El código de la Dll es

en el .CPP

Código
  1. extern "C" __declspec( dllexport ) __stdcall void Mensaje(char Titulo[], char* Mensaje)
  2. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(char *Titulo, char &Mensaje)
  3. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(const char *Titulo, char* Mensaje)
  4. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(const char Titulo, char* Mensaje)
  5. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(LPCTSTR Titulo, char* Mensaje)
  6. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(TCHAR *Titulo, char* Mensaje)
  7. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(unsigned char Titulo, char* Mensaje)
  8. {
  9.       /*char *Convertir(char cad[])
  10.        {
  11.             int i;
  12.             for ( i = 0 ; cad[i] != '\0' ; i++ )
  13.             if( i == 0 || cad[i-1]==' ' || cad[i+1]== ' ' || cad[i+1]=='\0')
  14.             if(cad[i] >= 'a' && cad[i] <= 'z') cad[i] -= 32;
  15.             return cad;
  16.        }
  17.        
  18.        Convertir(Titulo);
  19.        Convertir(Mensaje);*/
  20.  
  21.       //convertir char* a LPCTSTR
  22.       //LPCTSTR stringT = Titulo;
  23.  
  24.       //convertir char* a LPCSTR
  25.       //LPCTSTR stringT;// = Titulo;
  26.       //CString stringT;
  27.       //TCHAR stringT;
  28.       //t_char stringT[];
  29.       //stringT = Titulo;
  30.  
  31.       //LPCTSTR stringM;// (Mensaje);
  32.       //char stringM[54];
  33.       //stringM = Mensaje;
  34.  
  35.       //int MAX_PATH;
  36.       //MAX_PATH = 200;
  37.       //char szANSIString [MAX_PATH];
  38.       /*WideCharToMultiByte (CP_ACP, // página de códigos ANSI
  39.        WC_COMPOSITECHECK, // Verificar caracteres acentuados
  40.        //wszUNICODEString, // Cadena Unicode de origen
  41.        Titulo,
  42.        -1, // -1 significa que la cadena tiene terminación cero
  43.        //szANSIString, // cadena de caracteres de destino
  44.        stringT,
  45.        //sizeof (szANSIString), // Tamaño del búfer
  46.        sizeof (stringT),
  47.        NULL, // Sin carácter predeterminado
  48.        TRUE);  // No me importa esta bandera
  49.        */
  50.       //MessageBox(NULL, Titulo.c_str(), stringM, MB_ICONINFORMATION);
  51.       //MessageBoxA(NULL, stringT, stringM, MB_ICONINFORMATION);
  52.       //MessageBox(NULL, stringT, Mensaje, MB_ICONINFORMATION);
  53.       MessageBox(NULL, Titulo, Mensaje, MB_ICONINFORMATION);
  54. }
  55.  

En el .H
Código
  1. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(char* Titulo, char* Mensaje);
  2. extern "C" __declspec( dllexport ) __stdcall void Mensaje(char Titulo[], char* Mensaje);
  3. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(LPCSTR Titulo, char* Mensaje);
  4. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(char *Titulo, char &Mensaje);
  5. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(const char Titulo, char* Mensaje);
  6. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(LPCTSTR Titulo, char* Mensaje);
  7. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(TCHAR *Titulo, char* Mensaje);
  8. //extern "C" __declspec( dllexport ) __stdcall void Mensaje(unsigned char Titulo, char* Mensaje);
  9.  

En VB6

Código
  1. En VB6
  2.  
  3. Private Declare Sub Mensaje Lib "dll.dll" (Titulo As String, Mensaje As String)
  4.  
  5. Private Sub Command1_Click()
  6.       Mensaje "Este es el título", "Este es el mensaje"
  7. End Sub
  8.  

Al correr el ejecutable de VB6 me tira un mensaje con símbolos....

Gracias de antemano


Título: Re: Problema Dll C++ DevC++ y Visual Basic 6
Publicado por: Serapis en 11 Diciembre 2017, 02:27 am
VB6 puede operar con dos tipos de cadenas.
1 byte por carácter y con 2 bytes por carácter,  y para pasar de una a otras se utiliza la función Strconv (o bien hacerlo manualmente). Aparte las cadenas de longitud fija herencia de Basic más antiguos (QuickBasic)...
Básicamente si usa dos bytes por carácter, el segundo (los impares) debe ser un null (byte 0) y la cadena de texto siempre debe acabar en un null (el último byte par).

Cuando se usa en Dll, el error más común suele aparecer porque se considere o no el carácter de fin de cadena (null), o bien porque no se pase correctamente el puntero de la cadena.

Cuando proceda (o inténtalo y ver si así se resuelve tu problema), pasa un array de bytes. VB6 convierte automáticamente un array de bytes en cadena así como una cadena en un array de bytes, cuando se haga dicha asignación.
Código
  1. Private Sub Form_Load()
  2.    Dim miArray() As Byte
  3.    Dim texto As String, otroTexto As String
  4.    Dim k As Long
  5.  
  6.    texto = "ejemplo"
  7.    miArray = texto
  8.  
  9.    For k = 0 To UBound(miArray)
  10.        MsgBox Chr$(miArray(k))
  11.    Next
  12.    otroTexto = miArray
  13.    MsgBox otroTexto
  14. End Sub
  15.  
  16. Salida:
  17. E
  18. null
  19. j
  20. null
  21. e
  22. null
  23. m
  24. null
  25. p
  26. null
  27. l
  28. null
  29. o
  30. null
  31.  


Técnicamente un "string" en VB6 es un "BStr" de C.
https://msdn.microsoft.com/es-es/library/windows/desktop/ms221069(v=vs.85).aspx


Título: Re: Problema Dll C++ DevC++ y Visual Basic 6
Publicado por: Eleкtro en 11 Diciembre 2017, 09:30 am
Citar
Tengo entendido que VB6 usa Unicode y DevC++ Ansi.... y no encuentro como convertirlo....

Visual Basic hace la conversión automática a Unicode y ANSI cuando es requerido. Ese no es el problema.

Citar
Código
  1. Private Declare Sub Mensaje Lib "dll.dll" (Titulo As String, Mensaje As String)

La conversión de tipos parece correcta, en teoría deberías poder usar el datatype String en Visual Basic para char* y char [] (Array).

Tal vez el problema por el cual te salta un error nada mas iniciar el executable pueda ser debido a que ambos parámetros de tu función se están pasando por referencia en la declaración de Visual Basic (ya que por defecto en Visual Basic todos los parámetros se pasan por referencia a menos que utilices la palabra reservada ByVal), creo que el problema podría estar en que el primer parámetro de la función debería pasarse por valor. Prueba así:

Código
  1. Declare Sub NombrePúblico Lib "NombreLibrería.dll" Alias "Mensaje" (ByVal titulo As String, ByRef mensaje As String)

Aquí puedes encontrar información y ejemplos de interés:
  • Declaring a DLL Procedure | MSDN (https://msdn.microsoft.com/en-us/library/aa716201(v=vs.60).aspx)

PD: no programo en VB6 ni en C/C++, solo me limito a intentar resolver el problema haciendo suposiciones en base a las características de cada lenguaje.

Saludos.