Hola, tengo un problema, yo por ej creo una DLL en VB que posee lo siguiente:
Option Explicit
Public Function Mensaje(ByVal Msg As String) As String
Mensaje = Msg
End Function
Cuando lo llamo desde C++, por un MessageBox(NULL,MyFunction("Mensaje"),"CAPTION",MB_OK); me lo muestra vacío, alguna idea?
Y si tienen la solución a este Thread http://foro.elhacker.net/programacion_visual_basic/ayuda_callings_sub_y_functions-t307209.0.html sería un combo BOX :laugh:
.
Generar DLL Normal.
http://infrangelux.sytes.net/FileX/?dir=/BlackZeroX/Proyectos/Proyecto%20DLL%20Normal
Hook APIS
http://infrangelux.sytes.net/FileX/?dir=/BlackZeroX/Programacion/vb6/APIHOOK
Dulces Lunas!¡.
Interesante, pero como paso esto a C++?
Private Function MTrim(ByVal s As String) As String
Dim i As Long
Dim res As String
For i = 1 To Len(s)
If Mid$(s, i, 1) <> Chr$(0) Then
res = res & Mid$(s, i, 1)
End If
Next
MTrim = res
End Function
Cuando lo tenga en C++, teoricamente tendría que funcionar? :O:O:O. Desde ya muchas gracias.
Hola, finalmente pude lograrlo.
Código de la DLL:
MIREN QUE HAY COSAS QUE LAS PUSE PARA HACER DEDUCCIONES Y PRUEBAS.
Option Explicit
Public Const DLL_PROCESS_DETACH = 0 ':El proceso descarga la DLL
Public Const DLL_PROCESS_ATTACH = 1 ': Cuando un proceso carga la DLL
Public Const DLL_THREAD_ATTACH = 2 ': El proceso está recargando una DLL
Public Const DLL_THREAD_DETACH = 3 ':El proceso está descargando una Dll recargada
Public Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Public Function DllMain(hInst As Long, fdwReason As Long, lpvReserved As Long) As Boolean
Select Case fdwReason
Case DLL_PROCESS_DETACH
'No per-process cleanup needed
Case DLL_PROCESS_ATTACH
MsgBox "Project1.dll Injected!"
'MsgBox "End of Search!"
DllMain = True
Case DLL_THREAD_ATTACH
'No per-thread initialization needed
Case DLL_THREAD_DETACH
'No per-thread cleanup needed
End Select
'DllMain = True
End Function
Public Sub Mensaje()
MessageBox 0&, "Test", "Mensaje", 0&
End Sub
Public Function Suma(ByVal N1 As Long, ByVal N2 As Long) As Long
Suma = N1 + N2
'MessageBox 0, Suma, "Resultado", 0
End Function
'Public Function Mensaje2(ByVal Msg As String) As String
'Mensaje2 = Msg
'End Function
Public Function Mensaje2() As String
' Las cadenas de VB6 son Unicode y al usarla desde una DLL
' se hace un follón... así que debemos quitarles los Chr$(0)
' que tenga en medio
'Dim str As String * 4
'str = "Hola"
'Mensaje2 = str
Mensaje2 = "Esto es una prueba."
End Function
Public Function LenString(ByVal Cadena As String) As Integer
LenString = Len(Cadena)
End Function
Private Function MTrim(ByVal s As String) As String
Dim i As Long
Dim res As String
For i = 1 To Len(s)
If Mid$(s, i, 1) <> Chr$(0) Then
res = res & Mid$(s, i, 1)
End If
Next
MTrim = res
End Function
En C++, lo pueden abrir desde VC++ 6.0 (Mi favorito) o del VS 2009, etc.
HAY MUCHO CÓDIGO PORQUE PROBÉ DEMASIADAS COSAS.
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
typedef void (WINAPI*MsgFunction) ();
typedef long (WINAPI*SumaFunction) (long,long);
void MyDLL();
void MyDLL2();
void MyDLL3();
void MyDLL4();
string MTrim(char *);
string MTrim(char *, int);
int tStrLen(char *);
bool IsValid(char);
//Declaramos el ProcID de la dll
//HINSTANCE hGetProcIDDLL = LoadLibrary("Project1.dll");
int main()
{
MyDLL4();
/*
MsgFunction MsgBox;
SumaFunction Suma;
HINSTANCE hinstDLL = LoadLibrary("Project1.dll");
if(hinstDLL != 0)
{
printf("DLL LOADED.\n");
MsgBox = (MsgFunction)GetProcAddress(hinstDLL,"Mensaje");
MsgBox();
Suma = (SumaFunction)GetProcAddress(hinstDLL,"Suma");
long x = Suma(6,6);
if(x == 12)
{
cout << "Message Displayed!\n";
}
// Unload DLL file
FreeLibrary(hinstDLL);
}
else
{
printf("DLL NOT LOADED.\n");
}
*/
system("PAUSE");
return 0;
}
void MyDLL()
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("Project1.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress((HMODULE)hGetProcIDDLL,"Mensaje");
/*
Define the Function in the DLL for reuse. This is just prototyping
the dll's function. A mock of it. Use "stdcall" for maximum
compatibility.
*/
typedef void (__stdcall * pICFUNC)(HWND);
pICFUNC MyFunction;
if (hGetProcIDDLL==NULL)
{
printf("Can not open the Library\n");
}
else
{
printf("CAN open the Library\n");
}
MyFunction = (pICFUNC)lpfnGetProcessID;
/* The actual call to the function contained in the dll */
MyFunction(NULL);
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
}
void MyDLL2()
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("Project1.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress((HMODULE)hGetProcIDDLL,"Suma");
/*
Define the Function in the DLL for reuse. This is just prototyping
the dll's function. A mock of it. Use "stdcall" for maximum
compatibility.
*/
typedef long (__stdcall * pICFUNC)(long,long);
pICFUNC MyFunction;
if (hGetProcIDDLL==NULL)
{
printf("Can not open the Library\n");
}
else
{
printf("CAN open the Library\n");
}
MyFunction = (pICFUNC)lpfnGetProcessID;
/* The actual call to the function contained in the dll */
long x = MyFunction(5,5);
//printf("Result: %l\n",x);
cout <<"Resultado: ";
cout << x;
cout << '\n';
cout <<"Resultado: " << x <<'\n';
//cout <<"El valor decimal de número es:" << numero << '\n';
//cout <<"El valor octal de número es:" << oct <<numero << '\n';
//cout <<"El valor hexadecimal de número es:" << hex <<numero << '\n';
//Si se hace otro cout de algun numero, lo muestra en hex, xq fue
//el último que usamos
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
}
void MyDLL3()
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("Project1.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress((HMODULE)hGetProcIDDLL,"Mensaje2");
/*
Define the Function in the DLL for reuse. This is just prototyping
the dll's function. A mock of it. Use "stdcall" for maximum
compatibility.
*/
typedef char * (__stdcall * pICFUNC)(); //LPCSTR
//typedef void (CALLBACK* pICFUNC)();
pICFUNC MyFunction;
if (hGetProcIDDLL==NULL)
{
printf("Can not open the Library\n");
}
else
{
printf("CAN open the Library\n");
}
MyFunction = (pICFUNC)lpfnGetProcessID;
/* The actual call to the function contained in the dll */
//MessageBox(NULL, MyFunction(),"CAPTION",MB_OK);
char * ss = MyFunction();
//cout << MTrim(ss) << "\n";
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
}
void MyDLL4()
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("Project1.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress((HMODULE)hGetProcIDDLL,"Mensaje2");
FARPROC lpfnGetProcessID2 = GetProcAddress((HMODULE)hGetProcIDDLL,"LenString");
/*
Define the Function in the DLL for reuse. This is just prototyping
the dll's function. A mock of it. Use "stdcall" for maximum
compatibility.
*/
typedef char * (__stdcall * pICFUNC)(); //LPCSTR
typedef int (__stdcall * pICFUNC2)(char *); //LPCSTR
//typedef void (CALLBACK* pICFUNC)();
pICFUNC MyFunction;
pICFUNC2 MyFunction2;
if (hGetProcIDDLL==NULL)
{
printf("Can not open the Library\n");
}
else
{
printf("CAN open the Library\n");
}
MyFunction = (pICFUNC)lpfnGetProcessID;
MyFunction2 = (pICFUNC2)lpfnGetProcessID2;
/* The actual call to the function contained in the dll */
//MessageBox(NULL, MyFunction(),"CAPTION",MB_OK);
char * ss = MyFunction();
cout << "Longitud: " << MyFunction2(ss) << "\n\n";
cout << "Supuesta cadena: " << ss << "\n\n";
cout << "Forma Frutera: " << MTrim(ss) << "\n\n";
cout << "A la gran Misery: " << MTrim(ss, MyFunction2(ss)) << "\n\n";
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
}
string MTrim(char * s)
{
long i;
string res="";
char chr = char(0);
//cout << "Longitud: " << tStrLen("Hola") << "\n";
//cout << "Longitud: " << strlen(s) << "\n";
//cout << "Longitud: " << sizeof(s) << "\n";
//cout << "Longitud: " << s.length() << "\n";
for(i=0; i < 16 ;i++) //Testin'
{
if(s[i] != chr)
{
res = res + s[i];
}
}
return res;
}
string MTrim(char * s,int len)
{
long i;
string res="";
char chr = char(0);
int acum=0;
//cout << "Longitud: " << tStrLen("Hola") << "\n";
//cout << "Longitud: " << strlen(s) << "\n";
//cout << "Longitud: " << sizeof(s) << "\n";
//cout << "Longitud: " << s.length() << "\n";
for(i=0; acum < len ;i++) //Testin'
{
if(IsValid(s[i]) == true && s[i] != chr)
{
res = res + s[i];
acum++;
}
}
return res;
}
bool IsValid(char s)
{
char valid[] = "abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMÑOPQRSTUVWXYZ0123456789 ,.-!$%&/()=?¿*;_¬[]{}";
for(int i = 0; i < strlen(valid); i++)
{
if(valid[i] == s)
{
return true;
}
}
return false;
}
//Función que devuelve la longitud de una cadena
int tStrLen(char * s)
{
char * s0= s;
while (*s++);
return s - s0 - 1;
}
Lo último que hice fue basado en el, MyDLL4().
Lo que hago es llamar a la función de que me retorna un STRING, luego con una misma funcion de la DLL obtengo la longitud del string, porque no podía obtener la logitud verdadera.
MyFunction es el Mensaje, osea, lo que retorna la CADENA.
Con MyFunction2 obtengo la longitud.
Después uso un MTrim re frutero que lo hice después de muchos intentos xD.
El MTrim con 2 parámetros es el que nos interesa.
Que le paso la cadena y la longitud, y ahí está como hice, osea sólo permito ciertos dígitos y luego voy contando cuantos caracteres fueron agregandose para saber si es la longitud de la cadena.
char * ss = MyFunction();
cout << "Longitud: " << MyFunction2(ss) << "\n\n";
cout << "Supuesta cadena: " << ss << "\n\n";
cout << "Forma Frutera: " << MTrim(ss) << "\n\n";
cout << "A la gran Misery: " << MTrim(ss, MyFunction2(ss)) << "\n\n";
Bueno, desde ya muchísimas gracias a todos y a BlackZeroX por darme esa pista. :). Suerte.
PD: Obviamente está todo desprolijo y no optimizado, pero así estuve por más de 3 días. :)
PD2: Me falta hacer el pasaje del MessageBox.
Option Explicit
Public Function Mensaje(ByVal Msg As String) As String
Mensaje = Msg
End Function
Para mi el problema esta en que ninguna de las variables tienen informacion, es decir
que estan vacias.
intenta con la DLL asi:
Option Explicit
Public Function Mensaje(ByVal Msg As String) As String
Msg = "Hola Mundo!"
Mensaje = Msg
End Function
.
Interesantes codigos me ayudaran a crear Plugins de Otra manera, Se te agradece (Los codigos en C)!¡.
Dulce Infierno Lunar!¡.
.
Como Dato:
Private Function MTrim(ByVal s As String) As String
Dim i As Long
Dim res As String
For i = 1 To Len(s)
If Mid$(s, i, 1) <> Chr$(0) Then
res = res & Mid$(s, i, 1)
End If
Next
MTrim = res
End Function
Queda mejor asi!¡:
Private Function NullTrim(ByVal vDataIn As String) As String
Dim Lng_Pos As Long
Lng_Pos = InStr(1, vDataIn, Chr(0)) - 1
If Lng_Pos > 0 Then NullTrim = Mid$(vDataIn, 1, Lng_Pos)
End Function
Para quitar los chr(0) de los string (Unicode) solo se me ocurrre hacer esto en un array de bytes.
Dim arrbyte() As Byte
arrbyte() = StrConv("hola", VbStrConv.vbFromUnicode)
MsgBox Chr(arrbyte(0)) & Chr(arrbyte(1)) & Chr(arrbyte(2)) & Chr(arrbyte(3))
Dulces Lunas!¡.
Cita de: BlackZeroX▓▓▒▒░░ en 15 Octubre 2010, 04:35 AM
.
Como Dato:
Private Function MTrim(ByVal s As String) As String
Dim i As Long
Dim res As String
For i = 1 To Len(s)
If Mid$(s, i, 1) <> Chr$(0) Then
res = res & Mid$(s, i, 1)
End If
Next
MTrim = res
End Function
Queda mejor asi!¡:
Private Function NullTrim(ByVal vDataIn As String) As String
Dim Lng_Pos As Long
Lng_Pos = InStr(1, vDataIn, Chr(0)) - 1
If Lng_Pos > 0 Then NullTrim = Mid$(vDataIn, 1, Lng_Pos)
End Function
Para quitar los chr(0) de los string (Unicode) solo se me ocurrre hacer esto en un array de bytes.
Dim arrbyte() As Byte
arrbyte() = StrConv("hola", VbStrConv.vbFromUnicode)
MsgBox Chr(arrbyte(0)) & Chr(arrbyte(1)) & Chr(arrbyte(2)) & Chr(arrbyte(3))
Dulces Lunas!¡.
Si la función en VB tiene vbFromUnicode, en C++, se me crashea, eso lo pensé y lo intenté pero sin resultados favorables. :)
Lo has probado?
Cita de: Miseryk en 15 Octubre 2010, 18:27 PM
Si la función en VB tiene vbFromUnicode, en C++, se me crashea, eso lo pensé y lo intenté pero sin resultados favorables. :)
Lo has probado?
mmmm... Si no funciona esto entonces ya no se que es xP
Option Explicit
Private Sub Form_Load()
Dim arrbyte() As Byte
arrbyte() = StrConvFromUnicode("hola")
MsgBox Chr(arrbyte(0)) & Chr(arrbyte(1)) & Chr(arrbyte(2)) & Chr(arrbyte(3))
End Sub
Function StrConvFromUnicode(ByVal vData As String) As Variant
Dim lng_Index As Long
Dim Int_Asc As Integer
For lng_Index = 1 To Len(vData)
Int_Asc = Asc(Mid$(vData, lng_Index, 1))
If Int_Asc And &HFF00 Then
StrConvFromUnicode = StrConvFromUnicode & ChrB(Int(Int_Asc / 256) And &HFF)
StrConvFromUnicode = StrConvFromUnicode & ChrB(Int_Asc And &HFF)
Else
StrConvFromUnicode = StrConvFromUnicode & ChrB(Int_Asc)
End If
Next
End Function
Dulce Infierno Lunar!¡