Newsgroup: it.comp.lang.delphi
Titolo: DLL in C e FreeLibrary

Buongiorno a tutti, sto scrivendo una DLL in C (VC++ 6) che si occupa
di comunicare con una videocamera. Inizialmente, da Delphi caricavo la
DLL staticamente ma ora mi sono accorto che, per motivi che non sto ad
elencare, ho la necessità di liberare e ricaricare la DLL quindi
perchè non caricarla dinamicamente?
Il mio vero problema è quando chiamo la FreeLibrary, una volta
chiamata non mi ritorna più nulla e anche se debuggo dal C vedo la
chiamata alla DllMain che salta sul DLL_PROCESS_DETACH e esce
ritornando "true". A questo punto l'applicazione in Delphi dovrebbe
continuare ma invece nulla... è li che aspetta come se la DLL sta
ancora girando.
Dove sbaglio? Vi posto il codice di esempio che sto utilizzando:
1. DLL in C
#include "stdafx.h"
#include "DriverPleora3.h"
//*****************************************************************************************************
DRIVERPLEORA3_API int Somma(int a, int b)
//*****************************************************************************************************
{
return a + b;
}
//*****************************************************************************************************
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID
lpReserved)
//*****************************************************************************************************
{
    switch (ul_reason_for_call)	{
			case DLL_PROCESS_ATTACH:
				break;
			case DLL_PROCESS_DETACH:
				break;
			case DLL_THREAD_ATTACH:
				break;
			case DLL_THREAD_DETACH:
				break;
			}
    return TRUE;
}
--------------------------------------------------------------------------------------------------------------------------------
2. Applicazione DELPHI
Type
  TDLLSomma = function(Param1, Param2 : Integer):Integer; cdecl;
const
  DLL_PATH = '..\DriverPleora3\Debug\DriverPleora3.dll';
var
  Form1: TForm1;
  HInstance: LongWord;  // Indicates the handle for a module. (my DLL)
  FctSomma : TDLLSomma;
//******************************************************************************
procedure TForm1.Button1Click(Sender: TObject);
//******************************************************************************
begin
  HInstance := LoadLibrary(DLL_PATH);
  @FctSomma := GetProcAddress(HInstance, 'Somma');
  Panel1.Caption := IntToStr(FctSomma(1,2));
  // LA CAPTION DEL PANNELLO DIVENTA 3. PERFETTO !!
  // ORA CON BUTTON2 DEVO SCARICARE LA DLL
end;
//******************************************************************************
procedure TForm1.Button2Click(Sender: TObject);
//******************************************************************************
begin
  FreeLibrary(HMODULE(HInstance));
  Panel1.Caption := 'scaricata';
end;
Ringrazio in anticipo e mi scuso se mi sono dilungato un pò troppo....

 
A.

Ops.. Sorry ma avevo sbagliato a postare, si la FreeLibrary la chiamo
in questo modo:
FreeLibrary(HInstance);
Solo che le sto provando di tutte ma...
Allora dalla DLL ho tolto tutte le funzioni che non servono e TADAMM
funziona!
Allora non è un problema di FreeLibrary, o meglio...
Mi sono messo a debuggare un VC entrando nei meandri del distruttore
con F11 e alla fin fine mi sono accorto che si blocca proprio nel file
"CRT0DAT.C" di VC
...
...
if (!quick) {
            /*
             * do _onexit/atexit() terminators
             * (if there are any)
             *
             * These terminators MUST be executed in reverse order
(LIFO)!
             *
             * NOTE:
             *  This code assumes that __onexitbegin points
             *  to the first valid onexit() entry and that
             *  __onexitend points past the last valid entry.
             *  If __onexitbegin == __onexitend, the table
             *  is empty and there are no routines to call.
             */
            if (__onexitbegin) {
                _PVFV * pfend = __onexitend;
                while ( --pfend >= __onexitbegin )
                /*
                 * if current table entry is non-NULL,
                 * call thru it.
                 */
                if ( *pfend != NULL )
                    (**pfend)();       // <---- SI BLOCCA QUI
!!!!!!!!!!
            }
Sembra quasi che va a puntare ad un indirizzo di mem che non centra
nulla...
Come posso capire dov'è il problema?
Alberto Salvati ha scritto:


end;
Non userei HInstance, dal momento che c'e' gia una variabile globale di 
windows per la tua applicazione che usa questo nome.
Ciao Giorgio

Ok, giusta osservazione, ora ho cambiato il nome in DllHandle ma nada..
non mi ha risolto il problema. Si blocca sempre nello stesso punto.
Giorgio Padoan ha scritto:


Mettici anche un :
DisableThreadLibraryCall(HInstance) all'inizio della DLLMain
Giorgio 

Si Giorgio, non ho postato il codice aggiornato perchè sto continuando
a fare prove.
Questo  l'ho messo in...
...
...
case DLL_PROCESS_ATTACH:
  DisableThreadLibraryCalls(hInstance);
  break;
Ma non cambia nulla, o meglio, si cambia qualcosa perchè ora la
DllMain viene chiamata solo dalla LoadLibrary e dalla FreeLibrary però
non risolve il mio problema.
Si pianta sempre nello stesso punto.
Giorgio Padoan ha scritto:
