?
Ausgangssituation:
Verschiedene Funktionen in einer DLL sollen Datenbankoperationen ausführen.
Host Datei:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "uMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
typedef __declspec(dllimport) int __stdcall (*Test)(int nValue);
typedef __declspec(dllimport) int __stdcall (*StartMe)(int nValue);
TForm1 Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TestBTNClick(TObject *Sender)
{
HMODULE ModPPSDll = LoadLibrary ("PPSInterface.dll");
// Gibt es ein DLL-Handle, hole die Adresse der Funktion
if(ModPPSDll != NULL)
{
void* TestAddr = GetProcAddress (ModPPSDll, "Test");
// Gibt es die Funktionsadresse, rufe die Funktion auf
if(TestAddr != NULL)
{
Test FunTest = reinterpret_cast<Test>(TestAddr);
int nReturn = FunTest(EdValue->Text.ToInt());
EdReturn->Text = IntToStr(nReturn);
}
else
{
Application->MessageBox("Funktion konnte nicht geladen werden",Application->Title.c_str(),MB_OK|MB_ICONSTOP);
}
}
else
{
Application->MessageBox("DLL konnte nicht geladen werden",Application->Title.c_str(),MB_OK|MB_ICONSTOP);
}
FreeLibrary(ModPPSDll);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StartBTNClick(TObject *Sender)
{
HMODULE ModPPSDll = LoadLibrary ("PPSInterface.dll");
// Gibt es ein DLL-Handle, hole die Adresse der Funktion
if(ModPPSDll != NULL)
{
void* TestAddr = GetProcAddress (ModPPSDll, "StartMe");
// Gibt es die Funktionsadresse, rufe die Funktion auf
if(TestAddr != NULL)
{
StartMe start = reinterpret_cast<StartMe>(TestAddr);
int nReturn = start(EdEmpno->Text.ToInt());
EdEmpRet->Text = IntToStr(nReturn);
}
else
{
Application->MessageBox("Funktion konnte nicht geladen werden",Application->Title.c_str(),MB_OK|MB_ICONSTOP);
}
}
else
{
Application->MessageBox("DLL konnte nicht geladen werden",Application->Title.c_str(),MB_OK|MB_ICONSTOP);
}
FreeLibrary(ModPPSDll);
}
//---------------------------------------------------------------------------
DLL Datei:
// Version der Laufzeitbibliothek (RTL) verwendet:
//
// Wenn die DLL Funktionen exportiert, die String-Objekte (oder Strukturen/
// Klassen, die verschachtelte Strings enthalten) als Parameter oder Funktionsergebnisse übergibt,
// muß die Bibliothek MEMMGR.LIB im DLL-Projekt und anderen Projekten,
// die die DLL verwenden, vorhanden sein. Sie benötigen MEMMGR.LIB auch dann,
// wenn andere Projekte, die die DLL verwenden, new- oder delete-Operationen
// auf Klassen anwenden, die nicht von TObject abgeleitet sind und die aus der DLL exportiert
// werden. Durch das Hinzufügen von MEMMGR.LIB wird die DLL und deren aufrufende EXEs
// angewiesen, BORLNDMM.DLL als Speicherverwaltung zu benutzen. In diesem Fall
// sollte die Datei BORLNDMM.DLL zusammen mit der DLL weitergegeben werden.
//
// Um die Verwendung von BORLNDMM.DLL, zu vermeiden, sollten String-Informationen als "char *" oder
// ShortString-Parameter weitergegeben werden.
//
// Falls die DLL die dynamische Version der RTL verwendet, müssen Sie
// MEMMGR.LIB nicht explizit angeben.
//---------------------------------------------------------------------------
extern "C" _declspec(dllexport) int __stdcall Test(int nValue);
extern "C" _declspec(dllexport) int __stdcall StartMe(int v_empno);
int makeCon(int v_in);
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
CoInitialize(NULL);
if(reason == DLL_PROCESS_ATTACH && DMPPS == NULL)
{
DMPPS = new TDMPPS(Application);
}
else if(reason == DLL_PROCESS_DETACH && DMPPS != NULL)
{
delete DMPPS;
}
return 1;
}
//---------------------------------------------------------------------------
int __stdcall Test(int nValue)
{
return nValue * nValue;
}
int __stdcall StartMe(int v_empno)
{
return makeCon(v_empno);
}
int makeCon(int v_in)
{
int makeConRet = 99;
try
{
TADOConnection* con = new TADOConnection(Application);
con->ConnectionString = "Provider=MSDAORA.1;Password=tiger;User ID=scott;Data Source=test;Persist Security Info=True";
con->Open();
con->Close();
}
catch (Exception *ex)
{
return 123;
}
return makeConRet;
}
Wenn ich die Datenbankverbindung benütze kommt eine Fehlermeldung:
Zugriffsverletzung bei Adresse 40036887 in Modul 'rtl60.bpl' Lesen von Adresse 40642D6C
Ohne Datenbankverbindung geht alles normal...
Bin für jeden Tipp dankbar...
MfG
Slurm...