Создание простейшей динамически присоединяемой Dll

  • Автор темы DrMcSheen
  • Дата начала
D

DrMcSheen

Всем привет.
В изучении C++ Builder встал на этапе работы с библиотеками.
Для понимания работы dll, сделал библиотеку с единственной функцией TestDll(), выводящей мессагу "Dll OK".
Сделал к ней обработчик, ехе-шник с единственной кнопкой на форме, по нажатию на которую подгружается моя dll-ка и вызывается функция TestDll.
Всё скомпилировал, скопировал готовую dll в корень диска D: (так путь короче), запускаю, результат GetLastError после LoadLibrary == "Неверная попытка доступа к адресу памяти". Я не пойму, проблема в самой библиотеке или в ехе-шнике? Почему не работает?
Помогите, плиз. Проекты (отдельно dll и ехе) приложил. WinXP SP3, C++Builder 6.
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"TestDll_exe.cpp"</div></div><div class="sp-body"><div class="sp-content">
C++:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UTestDll_exe.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------



HINSTANCE dllInstance;
typedef void (__import * BType());
BType * TestDll = NULL;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
dllInstance = LoadLibrary("D:\\TestDll.dll");

LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL);
MessageBox(0,(const char *)lpMsgBuf, "Error", MB_OK|MB_ICONINFORMATION );

TestDll = (BType *)GetProcAddress(dllInstance, "_TestDll");
//TestDll();
}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
while(FreeLibrary(dllInstance));
}
//---------------------------------------------------------------------------
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"TestDll_dll.cpp"</div></div><div class="sp-body"><div class="sp-content">
C++:
#include <vcl.h>
#include <windows.h> 
#include "TestDll.h"

#pragma hdrstop

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//--------------------------------------------------------------------------- 
void TestDll()
{
ShowMessage("Dll OK");
}
//---------------------------------------------------------------------------
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"TestDll_dll.h"</div></div><div class="sp-body"><div class="sp-content">
C++:
#ifndef _TESTDLL_H
#define _TESTDLL_H

#ifdef __DLL__
# define DLL_EI __declspec(dllexport)
#else
# define DLL_EI __declspec(dllimport)
#endif
extern "C" void DLL_EI TestDll();
#endif
 

Вложения

  • TestDll_dll.rar
    334,8 КБ · Просмотры: 146
  • TestDll_exe.rar
    601,9 КБ · Просмотры: 156
G

Guest

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{ switch (reason) {
case DLL_PROCESS_ATTACH : case DLL_THREAD_ATTACH :
ShowMessage ("DLL connect"); break;
case DLL_PROCESS_DETACH : case DLL_THREAD_DETACH :
ShowMessage ("DLL disconnect"); break;
}
return 1;
}
//---------------------------------------------------------------------------
char FileName [256];
// описание функции DLL
extern "C" __declspec(dllexport) void Hello(bool);

//---------------------------------------------------------------------------
bool HelloToMe (void)
{
GetModuleFileName (NULL, FileName, sizeof (FileName));
MessageBox (NULL, "Hello, Master!", FileName, MB_OK);
return true;
};
//---------------------------------------------------------------------------

bool HelloToOther (void)
{ GetModuleFileName (NULL, FileName, sizeof (FileName));
MessageBox (NULL, "Hello!", FileName, MB_OK);
return false;
};
//---------------------------------------------------------------------------

void Hello (bool Who)
{ if (Who) HelloToMe(); else HelloToOther();
return;
}


далее ешник


typedef int (*Func)(bool);
void __fastcall TForm1::Button1Click(TObject *Sender)
{

HINSTANCE LibHandle = LoadLibrary ("g:\\Dll\\ExploreDll\\Hello.dll");
if (LibHandle != NULL) { // если DLL, то Hello()
Func pFunc = (Func) GetProcAddress (LibHandle, "_Hello");
if (pFunc == NULL) {
void *MessageBuf;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (),
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(char *) &MessageBuf, 0, NULL
);
:KillMe: :newconfus:
MessageBox (NULL, (char *) MessageBuf, "GetLastError", MB_OK | MB_ICONINFORMATION);
LocalFree (MessageBuf);
} else (*pFunc)(true);
};
while(FreeLibrary (LibHandle));
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!