PDA

Visualizza la versione completa : [C/C++] Problema con dll


Sprunk
07-12-2008, 16:30
Salve a tutti.
Non so usare le dll in C++.
ho usato l'ide visual studio 6.0 ed hos eguito dei consigli in rete.
Eccovi i miei codidi

DLL.cpp


// DLL.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

extern "C" int __declspec(dllexport) Somma(int a, int b)
{

return a+b;
}

Questo invece è il file di prova che la dovrebbe usare


void main()
{
HMODULE Hl = LoadLibrary("C:\\DLL\\Debug\\Dll.dll");
cout<<"Handle alla libreria \"C:\\DLL.dll\"\n"<<Hl<<"\n";
cout<<"Indirizzo funzione esportata \"Somma\"\n"<<GetProcAddress(Hl,"Somma")<<"\n";
cout<<"Indirizzo funzione esportata \"Pippo\" (Non esiste)\n"<<GetProcAddress(Hl,"Pippo")<<"\n";
int (*ptr)(int,int);
ptr=GetProcAddress(Hl,"Somma");
}

mi da questo errore all'ultima riga


error C2440: '=' : cannot convert from 'int (__stdcall *)(void)' to 'int (__cdecl *)(int,int)'

come se ptr puntasse ad una funzione senza parametri.
Aiutatemi per favore è da settimane che non riesco a trovare una soluzione.

Se possibile il risultato che vorrei è quello di avere un file .exe ed uan cartella con le librerie. Preferirei non portarmi dietro file strani come ad esempio un .def od altri
Grazie in anticipo. Cordiuali saluti. Ciaoo

shodan
07-12-2008, 17:45
E in queste settimane non hai pensato di cercare su MSDN? Un pò d'iniziativa che diamine.
http://msdn.microsoft.com/it-it/library/64tkc9y5(VS.80).aspx
Con tanto di esempio completo.

Sprunk
07-12-2008, 17:47
ci avevo giòà dato una occhiata, però non mi aveva risolto il problema. ora guardo in modo più approfondito

shodan
07-12-2008, 17:55
Se noti bene viene fatto un cast. Questo perchè la GetProcAddress restituisce un puntatore a funzione predefinito. Quindi per risolvere il tuo problema basta un semplice cast al tipo del tua funzione. (Personalmente ti consiglio un reinterpret_cast invece di un cast C-style, ma va bene pure quest'ultimo.)

Sprunk
07-12-2008, 17:56
Originariamente inviato da shodan
Se noti bene viene fatto un cast. Questo perchè la GetProcAddress restituisce un puntatore a funzione predefinito. Quindi per risolvere il tuo problema basta un semplice cast al tipo del tua funzione. (Personalmente ti consiglio un reinterpret_cast invece di un cast C-style, ma va bene pure quest'ultimo.)
si, l'ho notato. Ora lo stò provando. per adesso grazie mille. se avrò ancora problemi continuerò a postare in questa discussione

oregon
07-12-2008, 18:03
Ma ti serve proprio la LoadLibrary oppure puoi importare staticamente i rifierimenti alla DLL nel tuo exe (collegamento implicito)?

Sprunk
07-12-2008, 18:10
Rieccomi...

preferisco fare un collegamento esplicito, altrimenti mi tocca portarmi dietro oltre all'exe ed alla dll altri file, o sbaglio?

ho aggiornato il codice seguendo l'esempio di msdn


#include <iostream.h>
#include <windows.h>
typedef UINT (CALLBACK* LPFNDLLFUNC1)(INT,INT);
void main()
{
HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
INT uReturnVal;

hDLL = LoadLibrary("C:\\DLL\\Debug\\DLL.dll");
cout<<"Handle = "<<hDLL<<"\n";
if (hDLL != NULL)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
"Somma");
if (!lpfnDllFunc1)
{
// handle the error
FreeLibrary(hDLL);
MessageBox(0,"ERROR: Funzione non trovata","ERROR",MB_OK);
exit(0);
}
else
{
// call the function
uReturnVal = lpfnDllFunc1(1, 2);
}
}
else MessageBox(0,"FATAL ERROR: DLL NON CARICATA","FATAL ERROR",MB_ICONSTOP);

}

ma quando mi arriva ad eseguire la funzione mi da un errore.
Eccoti una foto dell'errore
http://sprunk.altervista.org/Upload/ERROR.bmp
Grazie ancora.

oregon
07-12-2008, 18:28
Originariamente inviato da Sprunk
Rieccomi...

preferisco fare un collegamento esplicito, altrimenti mi tocca portarmi dietro oltre all'exe ed alla dll altri file, o sbaglio?

Se parli della distribuzione, sbagli. Ti serve solo l'exe e la dll. E ti semplifichi la vita durante lo sviluppo.

shodan
07-12-2008, 18:33
A ogni modo, il puntatore a funzione deve corrispondere esattamente altrimenti si corrompe lo stack.

Originariamente inviato da Sprunk


#include <iostream.h>
#include <windows.h>
typedef INT (CALLBACK* LPFNDLLFUNC1)(INT,INT);
void main()
{
HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
INT returnVal; // <ritorna un int giusto?
...
else
{
INT a = 1;
INT b = 1;
// call the function
uReturnVal = lpfnDllFunc1(a,b);
}
}

Sprunk
07-12-2008, 18:33
ciò che mi interessa al momento è che, quando tutto sarà finito, per far funzionare il programma mi servano solo l'eseguigbile e la libreria dll. Con questi requisiti mi va bene qualsiasi metodo.
se non sei riuscito a vedere la foto dell'errore, eccoti il link dioretto
http://sprunk.altervista.org/Upload/ERROR.bmp

Loading