Я пытаюсь создать DLL в Embarcadero C++ Builder XE3 и использовать ее в тестовом проекте в той же среде.
Я беру пример с учебника, код которого не дает мне хорошего результата (!) : ="nofollow noreferrer">http://docwiki.embarcadero.com/RADStudio/XE3/en/Tutorial:_Using_Dynamic_Linked_Libraries_in_C%2B%2BBuilder_Applications
Вот содержимое моей DLL:
Файл BaseAuth.h:
#ifndef BaseAuthH
#define BaseAuthH
#include <System.hpp>
class TBaseAuth
{
public:
virtual void TestMessage() = 0;
};
#endif // BaseAuthH
Файл Auth.h:
//---------------------------------------------------------------------------
#ifndef AuthH
#define AuthH
//---------------------------------------------------------------------------
#include "BaseAuth.h"
class TAuth : public TBaseAuth
{
public:
TAuth();
~TAuth();
void TestMessage();
};
#endif
Файл Auth.cpp:
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Auth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TAuth::TAuth()
{
}
TAuth::~TAuth()
{
}
void TAuth::TestMessage()
{
MessageBox(0, "Test message", "Test", MB_OK);
}
и File1.cpp:
#pragma hdrstop
#pragma argsused
#include "Auth.h"
extern "C" __declspec(dllexport) void* __stdcall GetClassInstance()
{
return static_cast<void*>(new TAuth());
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
Теперь в тестовом приложении у меня есть:
тот же файл BaseAuth.h
форма с кнопкой:
Test_DLLAuthOrga.h:
#ifndef Test_DLLAuthOrgaH
#define Test_DLLAuthOrgaH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
#include "BaseAuth.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // Composants gérés par l'EDI
TButton *Button2;
void __fastcall Button2Click(TObject *Sender);
private: // Déclarations utilisateur
TBaseAuth *mpAuth;
public: // Déclarations utilisateur
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Test_DLLAuthOrga.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Test_DLLAuthOrga.h"
#include "BaseAuth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const wchar_t* library = L"DLLAuthOrga.dll";
extern "C" __declspec(dllimport) void* __stdcall GetClassInstance();
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
HINSTANCE load;
try
{ load = LoadLibrary(library); }
catch(Exception &e)
{ ShowMessage(e.Message); }
if (load)
{
ShowMessage("Library Loaded!");
void *myFunc;
myFunc = (void *)GetProcAddress(load, "GetClassInstance");
mpAuth = (AuthParent*)myFunc;
}
else { ShowMessage("Library not loaded!"); }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (mpAuth == NULL) return;
try { pRes = mpAuth->TestMessage(); }
catch(Exception &e) { ShowMessage(e.Message); return; }
}
Результат:
указатель mpAuth имеет адрес.
Но его методы не имеют адреса, и когда я вызываю простой метод, такой как "void TestMessage()", он вызывает нарушение прав доступа.
=> Сначала казалось, что это вопрос совместимости строк (но между «C++ Builder XE3» и «C++ Builder XE3» я ожидал бы, что будет использоваться один и тот же формат строки?!): Ошибка вызова DLL с Unicode Delphi
=> Я обнаружил аналогичную проблему, но с C++ DLL в Delphi, а не с C++ DLL в C++...: Вызов C++ DLL в приложении Delphi
=> Я попытался использовать «HMODULE» вместо «HINSTANCE load»; : тот же результат.
=> Я безуспешно пытался использовать
mpAuth = static_cast<AuthParent*>(myFunc);
вместо :
mpAuth = (AuthParent*)myFunc;
=> Я также пытался заменить «__stdcall» на «__cdecl» или «» (удаление): библиотека загружается, но GetProcAdress возвращает NULL.
=> Что я делаю неправильно, пытаясь вызвать метод DLL "TestMessage()"?