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

Тема в разделе "Borland C++ Builder & Kylix", создана пользователем DrMcSheen, 18 фев 2010.

  1. DrMcSheen

    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 КБ
      Просмотров:
      6
    • TestDll_exe.rar
      Размер файла:
      601,9 КБ
      Просмотров:
      6
  2. Гость

    #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));
     
Загрузка...

Поделиться этой страницей