Newsgroup: it.comp.lang.c++
Titolo: aiuto dll !!!!!!!

ho creato per prova una dll(molto banale) in VC++ 4 cosi fatta
long somma(long x , long y)
{
    int j ;
    j=x+y;
    return j;
}
Ma quando la vado a chiamare in un progetto vb5 mi da questo errore(bad Dll
calling Convention), io la dll in vb la dichiaro così
declare function somma& lib "mydll"(byval x& ,byval y&)
dove sbaglio ?
grazie a tutti per l'aiuto.

dove sbaglio ?
dovrebbe essere così:
declare function somma lib "mydll"(byval x as long , byval y as long) as
long
(OK il & dovrebbe funzionare lo stesso però, ma sai ... è Micr... ops)
Inoltre dipende da come hai dichiarato la funzione nella DLL. Probabilmente
la funzione "somma" non viene esportata con lo stesso nome.
Prova ad aggiungere alias "#1" alla dichiarazione (purché sia la
prima funzione della DLL)
Ci ho sbattuto la capoccia fino all'altro giorno e finalmente ne
sono uscito (quasi vivo).
Stesso problema.

la funzione "somma" non viene esportata con lo stesso nome.
Questo insieme di dichiarazioni funziona...:
in mydll.cpp:
	extern "C"
	long _stdcall somma(long x, long y)
	{
		return x+y;
	}
in mydll.def:
	LIBRARY     MYDLL
	DESCRIPTION "My DLL"
	EXPORTS
		somma @1
e in Visual Basic, esattamente come suggerito da Petrosky.
Ci sono sicuramente molte altre possibilita`, tipo l'alias che sempre
Petrosky suggerisce, ma almeno cosi` funziona... fattori principali:
-- extern "C"	garantisce che il simbolo sia proprio "somma" e non,
		ad esempio, ?somma@@YGJJJ@Z (come sarebbe senza di
		esso, con la name decoration che fa il VC++)
-- _stdcall     fondamentale, perche` e` quel che il VB prescrive
-- EXPORTS	normalmente il modo piu` semplice di controllare cosa
		e come si esporta dalla propria DLL
L'alternativa principale sarebbe di omettere l'extern "C" e l'intero
file .DEF, usando invece __declspec, come segue:
	__declspec(dllexport)
	long _stdcall somma(long x, long y)
	{
		return x+y;
	}
e in visual basic aggiungere alias "?somma@@YGJJJ@Z" (nome decorato).
I nomi decorati possono essere scoperti in vari modi, ad esempio
abilitando la produzione di un file di mappa (MYDLL.MAP), oppure
con il comando (da un prompt DOS nel directory opportuno...):
	dumpbin/exports mydll.dll
(ridirigendo opportunamente l'output, non e` difficile inserire
i nomi decorati nel programma VBasic con un po di copia/incolla).
Una soluzione piu` generale e` di usare il VC++ per generare, non
una generica DLL, bensi` specificamente un servente COM in-process,
che e` sempre una DLL ma con un insieme di convenzioni precise che
ne regola l'interfaccia.
File/New/Projects/ATL COM AppWizard/
    dare ad esempio il nome myatl e accettare i default;
Poi, da ClassView, click destro su "myatl classes", New Class,
    nome ad esempio mylib (magari togliere Aggregatable);
Ancora click destro, stavolta sulla risultante "Imylib"/Add Method...
    Method Name somma, Parameters long x, long y, [out, retval] long*z
Aprire la implementazione di mylib/Imylib/somma, aggiungere il
    corpo della funzione *z = x+y;
Build del progetto.
Questo da Visual Basic si usa cosi`:
	Project/References/Browse/trovare e aggiungere myatl.dll
nelle declarations:
	dim x as mylib
nella form_load:
	set x = new mylib
per usarlo:
	pippo = x.somma(a,b)
E` certo un pochetto piu` complesso che non generare una DLL
nuda e cruda, ma offre parecchi vantaggi in termini di
generalita`, manutenibilita`, eccetera.  Ad esempio, il VB
raccoglie automaticamente la "type library" incorporata nella
DLL di un server COM in-process, e quindi, senza bisogno di
aggiungere altro (in particolare, senza nessuna dichiarazione
da scrivere in VB!), offre le funzionalita` di browsing,
completion durante l'editing, eccetera.
Se non altro non c'e` da preoccuparsi di overhead; la myatl.dll
cosi` generata e` di 12288 byte nella configurazione min-size,
18,944 in quella min-dependency, rispetto a 28.672 byte per la
configurazione release della mydll.dll vista in precedenza:-).
Si possono fare altri tuning (ad esempio, la DLL cosi` fatta
e` "apartment threaded", cioe` con un certo supporto per il
multithreading -- se questo non interessa, si puo` spremere
qualche goccia in piu` di efficienza forzando il "single
threading" -- ecc, ecc), ma sono minuzie.
Alex
--
 ____    Alex Martelli, Bologna, Italia -- email: 
al...@magenta.com
 \SM/___                                 
http://magenta.com/~alex
  \/\bi/     You never know what is enough unless you know what
     \/          is more than enough.

}
Immagino che l'errore sia un altro ma proverň a contribuire: tu fai
ritornare un valore int a una funzione che, dal suo prototipo, dovrebbe
ritornare long.
Funziona meglio se fai cosě:
long somma(long x, long y)
{
    return x+y;
}
Ciao by Stefano from Italy
http://freeweb.aspide.it/free/imperial