PDA

View Full Version : Creare e utilizzare DLL Visual C++


swarm
29-06-2006, 10:28
Salve a tutti

mi ritrovo a dover realizzare una DLL, e già qui sono in alto mare....

volevo cmq chiedervi primaditutto una cosa....

creando la DLL, ad esempio con "WIN32 Dynamic Linked Library", e facendo creare al wizard la DllMain, perchè se tento di registrarla con regsvr32, perchè mi dice che nn riesce a trovare il punto di ingresso?

la DllMain creata è così (giàla conoscete, ovviamente)
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

che devo fare in più?

PS: visto che nn ne so molto, conoscete guide/link/siti da consultare per imparare l'ABC?

grazie a tutti

andbin
29-06-2006, 11:17
mi ritrovo a dover realizzare una DLL, e già qui sono in alto mare....

volevo cmq chiedervi primaditutto una cosa....

creando la DLL, ad esempio con "WIN32 Dynamic Linked Library", e facendo creare al wizard la DllMain, perchè se tento di registrarla con regsvr32, perchè mi dice che nn riesce a trovare il punto di ingresso?Ma devi sviluppare una DLL "normale" (che esporta solo funzioni) o una DLL che contiene componenti COM/ActiveX???

regsvr32.exe serve solo per registrare/deregistrare i componenti COM/ActiveX. Se devi creare una semplice DLL che esporta funzioni, non serve.

swarm
29-06-2006, 11:21
Ma devi sviluppare una DLL "normale" (che esporta solo funzioni) o una DLL che contiene componenti COM/ActiveX???

regsvr32.exe serve solo per registrare/deregistrare i componenti COM/ActiveX. Se devi creare una semplice DLL che esporta funzioni, non serve.

grazie, mi hai chiarito un primo dubbio...

in effetti la mia futura DLL dovrà contenere funzioni e variabili, ma potendo includerei anche un controllo COM (MSComm in particolare) e una ActiveX (stripchart)....

però se è molto + difficile n'fa niente, mi bastano già le funzioni.

che fo?

grazie!!!!!!!!

andbin
29-06-2006, 11:38
però se è molto + difficile n'fa niente, mi bastano già le funzioni.

che fo?Per esportare solo funzioni in genere si fa così (esempio):
BOOL WINAPI DllMain (HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpReserved)
{
....
}


__declspec(dllexport) VOID WINAPI NomeFunzione1 (....) { ... }

__declspec(dllexport) VOID WINAPI NomeFunzione2 (....) { ... }
...

swarm
29-06-2006, 11:58
ahem.....e per includere un controllo COM?

lascio perdere?


PS: dichiarando le funzioni come mi hai mostrato sopra, poi per utilizzare la DLL che fo?

devo utilizzare LoadLibrary?

te lo chiedo perchè, in una guida per il Visual C++, consigliava di utilizzare la dunzione BOOL WINAPI DllEntryPoint, dichiarare normalmente le funzioni (senza __declspec(***) ) e poi per chiamare le funzioni della DLL, utilizzare un HINSTANCE e un puntatore alla funzione, che riceveva l'indirizzo di quest'ultima mediante GetProcAddress()...

che casino!

andbin
29-06-2006, 12:16
ahem.....e per includere un controllo COM?Beh, la cosa è un po' più complicata ... comunque io non sono esperto di COM e ActiveX e quindi non so dirti più di tanto.
Se fai qualche ricerca troverai sicuramente molte informazioni.

PS: dichiarando le funzioni come mi hai mostrato sopra, poi per utilizzare la DLL che fo?

devo utilizzare LoadLibrary?

te lo chiedo perchè, in una guida per il Visual C++, consigliava di utilizzare la dunzione BOOL WINAPI DllEntryPoint, dichiarare normalmente le funzioni (senza __declspec(***) ) e poi per chiamare le funzioni della DLL, utilizzare un HINSTANCE e un puntatore alla funzione, che riceveva l'indirizzo di quest'ultima mediante GetProcAddress()...

che casino!Quando viene creata una DLL, il linker dovrebbe anche crearti un file .LIB che è la "import library" cioè una piccola libreria statica che dovrai usare, in fase di link, negli altri progetti in cui vuoi usare la DLL.
Questo è il metodo più diretto (e preferibile nella maggior parte dei casi). La libreria DLL viene caricata in modo dinamico quando l'eseguibile viene caricato dal S.O.

L'alternativa è usare LoadLibrary, ma è il programmatore che deve preoccuparsi di caricare la libreria, ottenere i puntatori alle funzioni, ecc...
Questo in genere va bene quando si deve gestire, ad esempio, un sistema a "plug-in" o realizzare dei tool specifici per le DLL.

Se non usi __declspec(dllexport) devi comunque dichiarare le funzioni da esportare in un file .DEF (da aggiungere al progetto della DLL).

swarm
29-06-2006, 14:00
Quando viene creata una DLL, il linker dovrebbe anche crearti un file .LIB che è la "import library" cioè una piccola libreria statica che dovrai usare, in fase di link, negli altri progetti in cui vuoi usare la DLL.

in pratica faccio le stesse cose come se fosse una libreria statica?

devo dichiarare un oggetto DLL?

o mi conviene inserire tutte le funzioni in una classe dichiarata nella DLL e poi istanzio un oggetto della classe?

scusa ma ho una gran confusione (come mio solito :cry: )

byez

andbin
29-06-2006, 14:23
in pratica faccio le stesse cose come se fosse una libreria statica?Più o meno .... la import library non contiene del codice ma solo i simboli e le informazioni che permetteno al linker di creare un eseguibile in modo tale che al suo avvio, possa poi caricare le DLL necessarie.

devo dichiarare un oggetto DLL?

o mi conviene inserire tutte le funzioni in una classe dichiarata nella DLL e poi istanzio un oggetto della classe?

scusa ma ho una gran confusione (come mio solito :cry: )

byezNo, non serve fare cose così complicate. Se in tuo altro progetto utilizzi la import library che hai creato, devi richiamare le funzioni nel modo normale, come per qualunque altra funzione!

Riprendendo l'esempio che ho fatto prima, basta che il compilatore conosca il prototipo della funzione, es:
VOID WINAPI NomeFunzione1 (....);

e poi la richiami semplicemente con:
NomeFunzione1 (...);

swarm
29-06-2006, 14:42
Più o meno .... la import library non contiene del codice ma solo i simboli e le informazioni che permetteno al linker di creare un eseguibile in modo tale che al suo avvio, possa poi caricare le DLL necessarie.

No, non serve fare cose così complicate. Se in tuo altro progetto utilizzi la import library che hai creato, devi richiamare le funzioni nel modo normale, come per qualunque altra funzione!

Riprendendo l'esempio che ho fatto prima, basta che il compilatore conosca il prototipo della funzione, es:
VOID WINAPI NomeFunzione1 (....);

e poi la richiami semplicemente con:
NomeFunzione1 (...);

grazie!

proverò, implementerò, riferirò :D

swarm
29-06-2006, 15:55
ciao

allora, io per provare ho fatto una cosa del genere.

Utilizzando da VC++ 6.0 la modalità "Win32 Dynamic Linked Library", scegliendo la DLL che può esportare variabili e funzioni, ho fatto così

file header
#ifdef DLL1_EXPORTS
#define DLL1_API __declspec(dllexport)
#else
#define DLL1_API __declspec(dllimport)
#endif

// This class is exported from the DLL1.dll
class DLL1_API CDLL1 {
public:
CDLL1(void);
// TODO: add your methods here.
int Somma (int a, int b);
int risultato;
};

extern DLL1_API int prodotto;

DLL1_API int Moltiplicazione (int x, int y);

mentre il file cpp è

#include "stdafx.h"
#include "DLL1.h"

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}


DLL1_API int Moltiplicazione(int x, int y)
{
int prod;

prod = x * y;

return prod;
}


// This is the constructor of a class that has been exported.
// see DLL1.h for the class definition
CDLL1::CDLL1()
{
return;
}

CDLL1::Somma(int a, int b)
{
risultato = a + b;

return risultato;
}


ho provato in un'applicazione dialog e funziona tutto, sia usando semplicemente le funzioni esportate, sia dichiarando un oggetto della classe creata.

ho semplicemente incluso il file .h della dll ed aggiunto al progetto il file .lib

così facendo, la dll sarà utilizzabile dagli altri ambienti, come VB oppure .NET?

ciao e grazie infinitamente!

71104
29-06-2006, 16:39
così facendo, la dll sarà utilizzabile dagli altri ambienti, come VB oppure .NET? si, è una normalissima DLL

swarm
29-06-2006, 17:02
si, è una normalissima DLL

me tapino! :cry: :cry:

ho scoperto che ho assoluto bisogno di includere un controllo COM, e forse anche un ActiveX

Ho quindi creato un progetto "MFCAppWizard Dll", come una Regular DLL che usa le MFC in modo shared

però questa come la uso?

se inserisco le funzioni che mi servono nella classe CDLLMFCApp (supponendo che la DLL l'abbia chiamata DLLMFC.dll), come devo usarla in un progetto dell'applicazione?

ovviamente (credo) facendo in modo di creare un oggetto CDLLMFCApp nell'applicazione, mi dà errore di link (ho fatto #include "DLLMFC.h" ed inserito il file DLLMFC.lib)

help! :mc:

swarm
30-06-2006, 13:08
me tapino! :cry: :cry:

ho scoperto che ho assoluto bisogno di includere un controllo COM, e forse anche un ActiveX

Ho quindi creato un progetto "MFCAppWizard Dll", come una Regular DLL che usa le MFC in modo shared

però questa come la uso?

se inserisco le funzioni che mi servono nella classe CDLLMFCApp (supponendo che la DLL l'abbia chiamata DLLMFC.dll), come devo usarla in un progetto dell'applicazione?

ovviamente (credo) facendo in modo di creare un oggetto CDLLMFCApp nell'applicazione, mi dà errore di link (ho fatto #include "DLLMFC.h" ed inserito il file DLLMFC.lib)

help! :mc:
raga vi prego aiutatemi!

non riesco nemmeno a dichiarare un oggetto CString o COleVariant, mi dice

C:\RGB\WelchAllynDLL\WelchAllynDLL.h(107) : error C2146: syntax error : missing ';' before identifier 'str1'
C:\RGB\WelchAllynDLL\WelchAllynDLL.h(107) : fatal error C1004: unexpected end of file found

dove avevo scritto

extern WELCHALLYNDLL_API CString str1;

se dichiaro solo CString str1;

mi dice "missing type specific"