Newsgroup: it.comp.programmare.win32
Titolo: Dll - GetProcAddress - Aiuto

Salve a tutti,
ho sviluppato con Visual C++ 6.0 una Dll win32 utilizzando nella
dichiarazione delle funzioni da esportare la parola chiave
__declspec(dllexport).
Se ho ben capito, tale parola chiave mi dovrebbe evitare l'utilizzo di un
file .DEF per l'esportazione delle funzioni della mia Dll.
Il guaio è che funziona a metà.
Mi spiego....
Se provo a chiamare le funzione della dll utilizzando le LoadLibrary e
GetProcAddress, quest'ultima mi funziona solo se invece di passargli il nome
della funzione gli passo il numero progressivo.
Perchè??
Grazie a chi saprà darmi un consiglio!
Daniele

 ha scritto nel messaggio
news:98c7tg$i7g$1...@nreadA.inwind.it...

Ho scoperto il perchè ma ne ho un altro da sottoporvi,
Il fatto che non riesca a trovare le funzioni per nome è semplicemente
perchè nella dll le funzioni non si chiamano come dovrebbero, ne avviene una
rielaborazione.
Esempio:
La funzione nel codice l'ho dichiarata così:
    __declspec(dllexport) int __stdcall LOAD(HWND hwnd, HINSTANCE hinst,
char* title)
nella dll me la ritrovo così:
?LOAD@@YGHPAUHWND__@@PAUHINSTANCE__@@PAD@Z
Intuisco che mi ci abbia codificato i parametri ma perchè?
E come faccio per avere solo il nome della funzione?
Devo necessariamente usare un file DEF?

 Daniele
Mhhh, vediamo un pò, personalmente quando creo qualche DLL non la carico con
LoadLibrary ma uso l'header della mia DLL per includerla nel progetto
(insieme al file .lib generato durante la compilazione della stessa DLL).
La parola chiave __declspec(dllexport) serve a dire al Visual (per quanto ne
so io) che deve generare un file .lib da includere nel progetto per poter
usare il link dinamico senza dover usare la funzione LoadLibrary. (Che
naturalmente si può usare lo stesso)
In questo modo è molto più semplice e non bisogna smanettare con il file
.DEF
Io includo l'header nel progetto e tutto va alla perfezione, senza dover
maneggiare con la GetProcAddress.
Chiamo direttamente le funzioni senza preoccuparmi della storia dei
puntatori.
Io ti consiglio di usare questo metodo, del resto non ho mai usato la
LoadLibrary e non posso aiutarti sulla questione della GetProcAddress.
Comunque la spiegazione potrebbe essere la seguente (riporto un pò dell'help
del msdn)
If you are exporting functions in a C++ file, you will have to either place
the decorated names in the .DEF file or define your exported functions with
standard C linkage by using extern "C". If you need to place the decorated
names in the .DEF file, you can obtain them by using the tool DUMPBIN or by
using the linker switch /MAP. Note that the decorated names produced by the
compiler are compiler specific. If you place the decorated names produced by
the Visual C++ compiler into a .DEF file, applications that link to your DLL
must also be built using the same version of Visual C++ so that the
decorated names in the calling application match the exported names in the
DLL's .DEF file.
Se compili in C++ devi quindi inserire il nome esatto prodotto dal
compilatore per la funzione e un nome interno di una funzione in C++ è
qualcosa del tipo _stampa@@int@@32 e robe del genere e quindi non coincide
esattamente con il nome che tu definisci nel tuo file CPP.
Quindi potrebbe essere che semplicemente la GetProcAddress non funziona
perché non trova il nome del file.
Una soluzione potrebbe essere dichiarare le funzione con extern "C" o usare
le opzioni del Linker /MAP o usare DUMPBIN.
Attento al fatto che per usare la libreria bisogna usare la stessa versione
del compilatore se si usano i nomi dei file "decorati".
Altro non so.
Spero di essere stato utile.
Nicola.

 Devo necessariamente usare un file DEF?
Beh ti modifica i parametri perché il C++ permette la definizioni di
funzioni overloaded, cioč con lo stesso nome formale ma con argomenti
diversi tipo:
void load(int a);
void load(char* a);
E' naturale che in questo caso il compilatore deve trovare il modo di
"trovare" l'esatta funzione da collegare mentre linka. Quindi fonde i
parametri assieme al nome della funzione per avere una definizione univoca
(quanto mi piace questa parola).
Spero di averti aiutato.
Nicola.

Ti ringrazio ora ne so di piů.
Non avevo pensato alle funzioni overloaded.
Il motivo per cui sono costretto a utilizzare la LoadLibrary e che non la
utilizzo io ma il programma per cui sto facendo un plugin Dll.
Quindi ho bisogno che i nomi delle funzioni coincidano con quelli
"ufficiali".
Ho trovato cmq una soluzione č bastato aggiungere il parametro
/EXPORT:NomeFunzione all Link e questo mi ha sostituito nella tabella di
esportazione il nome decorato.
Fortuna che le funzioni erano solo 3.
Adesso posso andare a dormire tranquillo ;-)
Ciao






wrote:

E' + semplice mettere un extern "C" davanti alla funzione, che non
viene modificato.
Penso che questa soluzione sia migliore anche perché non č specifica
di VC++.
Ciao
Marco Barisione (ICQ 84277092)



 di VC++.
Grazie per la dritta farò senz'altro così è molto più comodo.
Ciao.
P.S. Scusate per il posting ripetitivo del mio ultimo messaggio ma outlook
express era convinto di non averlo spedito!

E come faccio per avere solo il nome della funzione?
E' un fenomeno proprio dei compilatori C++.
Si chiama "name mangling" (decorazione dei nomi).
Racchiudi la tua funzione in un corpo :
extern "C" {
}
e abolirai questa operazione da parte del compilatore.