Kod testowej biblioteki dll mającej za zadanie umieścić danych w TListView jest następujący:
#include <windows.h>
#pragma hdrstop
#pragma argsused
extern "C" __declspec(dllexport) void __stdcall DoTestDll(TListView* );
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
void __stdcall DoTestDll(TListView* ListView1)
{
for (int jj=1; jj <= 10; jj++)
{
TListItem * ElementListy = ListView1->Items->Add();
ElementListy->Caption = "Dane z DLL: "+(String) jj;
ElementListy->SubItems->Add("---");
}
}
Testowy kod formularza wywołujący funkcję z DLL'ki:
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
//#pragma comment(lib, "TestDll.lib")
TForm3 *Form3;
//extern "C" __declspec(dllimport) void __stdcall DoTestDll(TListView *);
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button2Click(TObject *Sender)
{
for (int jj=1; jj <= 10; jj++)
{
TListItem * ElementListy = ListView1->Items->Add();
ElementListy->Caption = "Dane: "+(String) jj;
ElementListy->SubItems->Add("---");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button3Click(TObject *Sender)
{
//DoTestDll(ListView1);
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button4Click(TObject *Sender)
{
typedef void ( * pcDoDll )( TListView *ListView1 );
HINSTANCE biblio = LoadLibrary("TestDll.dll");
if (biblio == NULL)
{
ShowMessage("Brak pliku");
}
else
{
pcDoDll _WykonajZDll = (pcDoDll)GetProcAddress(biblio,"DoTestDll");
if (_WykonajZDll !=NULL)
{
_WykonajZDll(ListView1);
}
}
FreeLibrary(biblio);
}
//---------------------------------------------------------------------------
void __fastcall TForm3::Button1Click(TObject *Sender)
{
Application->Terminate();
}
Problem jest taki, że przy wywoływaniu funkcji z DLL ładowanego dynamicznie dane są wczytane do TlistView, ale przy zamykaniu formularza [ okna programu] wywalany jest wyjątek do tego dwa razy ten sam:
"First chance exception at $7C812AFB. Exception class EAccessViolation with message 'Access violation at address 0042A23D in module 'Project1Formularz.exe'. Write of address 00D206CC'. Process Project1Formularz.exe (2620)" |
Jeśli wykomentuję zwalnianie biblioteki DLL //FreeLibrary(biblio); wyjątek nie jest emitowany, ale tak być nie może.
Pytanie brzmi dlaczego tak się dzieje