Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
1

Работа с DLL ом, загляните на 1 минуту

28.05.2011, 18:03. Показов 1467. Ответов 15
Метки нет (Все метки)

Здрасте всем, создаваю длл по примером, и пытаюс истользовать его в моём приложение вот код из моего приложение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit24.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm24 *Form24;
 
 
//---------------------------------------------------------------------------
__fastcall TForm24::TForm24(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm24::Button1Click(TObject *Sender)
{
typedef void __cdecl (*dll_func)(const int A, const int B);
 
dll_func pShowSum = NULL;
 
HMODULE hDLL = LoadLibrary(L"D:\\MyDLL.dll");
if (!hDLL) {
  ShowMessage(L"Невозможно загрузить TestDLL.dll");
  return;
}
 
// пытаемся найти в таблице экспорта необходимую нам функцию
pShowSum = (dll_func)GetProcAddress(hDLL, "_ShowSum"); // обратите название на название функции (объяснение будет ниже)
 
if (!pShowSum) {
  ShowMessage(L"Невозможно найти функцию ShowSum");
  return;
}
 
pShowSum(3,2);
 
FreeLibrary(hDLL);
}
//---------------------------------------------------------------------------
И вот код с длл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#ifndef __MyDLL_H
#define __MyDLL_H
 
/*
символ TESTDLL_EXPORTS по умолчанию определен в Вашем проекте (см. Project Options -> С/С++ -> General->Preprocessor Definitions).
При этом все экспортируемые идентификаторы предваряются символом DLL_SPEC.
В случае определения TESTDLL_EXPORTS в проекте DLL_SPEC определяется как экспортируемый объект; в случае же отсутствия такого определения мы получим импортируемый объект.
Таким образом, один и тот же заголовочный файл может быть использован и в DLL-проекте, и в проекте, который будет использовать данную DLL! Без каких-либо изменений.
*/
 
#ifdef MyDLL_EXPORTS
#define DLL_SPEC extern "C" __declspec(dllexport)
 
#else
#define DLL_SPEC extern "C" __declspec(dllimport)
#endif // TESTDLL_EXPORTS
 
/*
Каждый экспортируемый идентификатор предваряем __declspec(dllexport).
Эта директива позволяет линкеру определить, что данный идентификатор следует экспортировать из DLL. При этом создается специальный lib-файл, который содержит все экспортируемые идентификаторы из модуля. Также экспортируемые объекты заносятся в раздел экспорта DLL.
*/
 
 
 
#endif // __TESTDLL_H
//Тут тоже пробовал обявить функцию, но всё равно не работает
//void ShowSum(const int A, const int B)
//{
// ShowMessage(IntToStr(A) + " + " + IntToStr(B) + " = " + IntToStr(A + B));
//}
 
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
 
#pragma argsused
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpReserved)
{
void ShowSum(const int A, const int B)
{
 
  ShowMessage(IntToStr(A) + " + " + IntToStr(B) + " = " + IntToStr(A + B));
}
    return 1;
}
//---------------------------------------------------------------------------
Приложение компилируется отлично, но все равно на Button1Click показывает сообшение

"Невозможно найти функцию ShowSum"

Что мне сделать помогите люди добрые?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.05.2011, 18:03
Ответы с готовыми решениями:

Переменная выдает 1 минуту одну картинку 2 минуту другую
Здравствуйте, подскажите php код, нужно что бы перейдя по странице открывалась 1 картинка, а если...

загляните...БД Библиотеки
вообщем так: Нужно чтобы осуществлялась фиксация книг на руки, возможность сохранения информации о...

загляните пожалуйста сюда...
Дан массив из 15 чисел. Переписать из него в другой массив только четные числа. Содержимое...

Блок-схемы алгоритмов, пожалуйста, загляните
Привет всем... Кто поможет составить блок схемы алгоритмов? Ну и проверить уже сделанные мной) 50...

15
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 18:27 2
Если честно ты тут какуе то хе......ню наделал....
  1. DllEntryPoint не трогай вообще
  2. В длл рекомендуетс использовать char тип к строкам ну или wchar_t
  3. так как ты ее динамически подключаешь тебе не нужно делать декларации на экспорт импорт так как они нужны только при статическом связывании!

Вот пример что ты хотел сделать, и опять же см. 2 пункт и пользуйся MessageBox'ом
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
 
//Смысл это строки, что бы к именам функция прибовлялся знак подчеркивания, а не генерировались свои имена
extern "C"
{
    //Объявляем ее на экспорт с соглашение __stdcall - про это на wiki можешь прочитать
    void __declspec(dllexport) __stdcall ShowSum(const int,const int);
}
 
#pragma argsused
//не трогай ее вообще, только в исключительных случаях.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
    return 1;
}
//---------------------------------------------------------------------------
 
//собственно сама функция
void __declspec(dllexport) __stdcall ShowSum(const int a1,const int a2)
{
    ShowMessage((UnicodeString)a1+"+"+(UnicodeString)a2+"="+(UnicodeString)(a1+a2));
 
}
далее, потом уже свое приложение делаем
в разделе private класса формы делаешь так
C++
1
2
3
4
5
6
7
private:    // User declarations
    //Указатель на длл
    HINSTANCE a;
    //создаем тип указатель на функцию
    typedef void (__stdcall *_ShowSum)(const int,const int);
           //Указатель на функцию
    _ShowSum ShowSum;
Далее при создании грузишь библиотеку и саму функцию, а так же при отключении программы, выгружаешь ее из памяти
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
//Загружаем саму билиотеку
this->a = LoadLibrary("d:\\cpp\\123.dll");
//проверяем, загрузилась ли? если нет, ошибка
if (!a)
{
    ShowMessage("Библиотека не загружена");
}else{
    //Если да, Загружаем адрусс функции
    this->ShowSum = (_ShowSum)GetProcAddress(this->a,"ShowSum");
    //Так же проверяем
    if (!ShowSum)ShowMessage("Ошибка загрузки функции");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
//Выгружаем библиотеку
FreeLibrary(this->a);
}
Ну а дальше используем
C++
1
2
3
4
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//Собственно сама функция
ShowSum(100,50);
1
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 19:04  [ТС] 3
pomkalk,
всё так сделал как вы сказали но программа ф-цию опять не может загрузит из длла!

Добавлено через 5 минут
И кода нажымаю на Button1 выдайт такую ошибку
Миниатюры
Работа с DLL ом, загляните на 1 минуту  
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 19:12 4
Попробуй отдельно проект создай DLL, скомпилируй, а потом только саму программу!
Я не знаю, я всегда в разных программах делал dll, или по очереди, либо два буилдера открывал!
0
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 19:56  [ТС] 5
pomkalk,
Спасибо всё равно
Сама DLL без хост программы не сможет скомпилироватся, Дело не в проекте и не в компоновке, дело с адресах я думаю.
Ну кто сможет помоч?
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 20:08 6
Programmer., всмысле как не сможет с компилироваться??))))) построй проект и все, в папке debug или debug/win32будет сама длл
Длл это такая же программа, только у нее нет "точки старта"(это как maim или WinMain) и все, так же прекрасно компилится

Добавлено через 5 минут
Это при статическом связывании имеет смысл в Группу заключать, а при динамическом, нет!!!

Добавлено через 32 секунды
Скинь еще весть код твоей новой ДЛЛ, а так же код все программы .cpp и .h
0
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 20:11  [ТС] 7
pomkalk,
DLL:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
extern "C"
{
    void __declspec(dllexport) __stdcall ShowNum(const int, const int);
}
#pragma argsused
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
 
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}
//---------------------------------------------------------------------------
void __declspec(dllexport) __stdcall ShowSum(const int a1, const int a2)
{
    ShowMessage((UnicodeString)a1+"+"+(UnicodeString)a2+"="+(UnicodeString)(a1+a2));
}
cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit24.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm24 *Form24;
//---------------------------------------------------------------------------
__fastcall TForm24::TForm24(TComponent* Owner)
    : TForm(Owner)
{
//Загружаем саму билиотеку
this->a = LoadLibrary(L"d:\\MyDLL.dll");
//проверяем, загрузилась ли? если нет, ошибка
if (!a)
{
        ShowMessage("Библиотека не загружена");
}else{
        //Если да, Загружаем адрусс функции
        this->ShowSum = (_ShowSum)GetProcAddress(this->a,"ShowSum");
        //Так же проверяем
        if (!ShowSum)ShowMessage("Ошибка загрузки функции");
}
}
//---------------------------------------------------------------------------
 
void __fastcall TForm24::Button1Click(TObject *Sender)
{
  ShowSum(1,2);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm24::FormDestroy(TObject *Sender)
{
FreeLibrary(this->a);
}
//---------------------------------------------------------------------------
.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//---------------------------------------------------------------------------
 
#ifndef Unit24H
#define Unit24H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm24 : public TForm
{
__published:    // IDE-managed Components
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormDestroy(TObject *Sender);
private:    // User declarations
  HINSTANCE a;
        //создаем тип указатель на функцию
        typedef void (__stdcall *_ShowSum)(const int,const int);
           //Указатель на функцию
        _ShowSum ShowSum;
public:     // User declarations
    __fastcall TForm24(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm24 *Form24;
//---------------------------------------------------------------------------
#endif
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 20:19 8
Вроде все правильно, когда программу запускаешь, ошибок ни каких нет?

попробуй все таки по отдельности, сначала сделай длл, а потом сам проект!!

Добавлено через 41 секунду
C++
1
        this->ShowSum = (_ShowSum)GetProcAddress(this->a,"_ShowSum");
Можешь так еще попробывать
0
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 20:29  [ТС] 9
pomkalk,
Так тоже пробовал, не работает, по отделности проект компилируется, но по отделности длл требует хост программу! но в Debug или Release создается отлично, спасибо всё равно, ест тут ктото тот поможет мне?
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 20:49 10
Почитай тогда про длл сначала!!! пригодится!!
1
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 21:00  [ТС] 11
pomkalk,
А можете дать харошие примери? Или книжку? то что дали там о Visual Studio а мне нужно в билдере
0
365 / 247 / 24
Регистрация: 03.04.2011
Сообщений: 558
Записей в блоге: 1
28.05.2011, 21:19 12
Тот что я тебе скинул, у меня работает на ура! Embarcadero RAD Studio c++ builder 2010, в гугле набери, dll в c++ builder
0
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
28.05.2011, 23:03  [ТС] 13
Едва ли мой билдер сума сехал?
0
Прогер
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
24.10.2011, 03:52  [ТС] 14
блин опять ето ошибка, не знаю что ему не нравится

Вот длл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <vcl.h>
#include <windows.h>
 
#pragma hdrstop
#pragma argsused
extern "C"
{
    __declspec(dllexport) __stdcall Restart(HWND);
}
 
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
    return 1;
}
 __declspec(dllexport) __stdcall Restart(HWND hWnd)
 
{
 HINSTANCE oPen;
 BOOL hProc;
 UnicodeString fpath = ExtractFilePath(Application->ExeName)+"BaseC.exe";
   oPen = ShellExecute(hWnd,L"open",fpath.c_str(),NULL,NULL,SW_SHOW);
   if(!oPen)
     {
       hWnd = 0;
       PROCESS_INFORMATION pi;
       STARTUPINFO si;
       si.cb = sizeof(STARTUPINFO);
       ZeroMemory(&si,sizeof(STARTUPINFO));
        hProc = CreateProcess(fpath.c_str(),
                              NULL,
                              NULL,
                              FALSE,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              &si,
                              &pi);
    }
    else if(hProc!=0) return 0;
}
Вот .Н:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//---------------------------------------------------------------------------
 
#ifndef Unit5H
#define Unit5H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm5 : public TForm
{
__published:    // IDE-managed Components
    TLabel *Label1;
    TButton *Button1;
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:     // User declarations
     HINSTANCE hLoad;
         typedef void (_stdcall *_Restart)(HWND);
         _Restart Restart;
    __fastcall TForm5(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm5 *Form5;
//---------------------------------------------------------------------------
#endif
Вот и са СРР:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <vcl.h>
#pragma hdrstop
 
#include "Unit5.h"
#include "tchar.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm5 *Form5;
UnicodeString path = ExtractFilePath(Application->ExeName)+"rs.dll";
//---------------------------------------------------------------------------
__fastcall TForm5::TForm5(TComponent* Owner)
    : TForm(Owner)
{
 this->hLoad = LoadLibrary(path.c_str());
  if(!this->hLoad)
   {
     MessageBox(Handle,_TEXT("ვერ მოიძებნა rs.dll ფაილი"),
                       _TEXT("შეცდომა"),
                       MB_ICONWARNING|MB_OK);
     }
     else
      {
       this->Restart = (_Restart)GetProcAddress(this->hLoad,"_Restart");
        if(!this->Restart)
         {
            ShowMessage("Func prob");
         }
 
 
      }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm5::Button1Click(TObject *Sender)
{
Restart(Handle);
}
//---------------------------------------------------------------------------
Миниатюры
Работа с DLL ом, загляните на 1 минуту  
0
40 / 60 / 8
Регистрация: 16.11.2012
Сообщений: 459
Записей в блоге: 7
19.11.2012, 14:49 15
Programmer., тема конечнго же мертва, но всё же. судя по ошибке которая вылетает (Access violation at address ) обычно вылетает из-за того что вы обращаетесь либо к еще не выделенной памяти , либо к уже освобожденной...
З,Ы, пишу для тех кому наверное понадобится
0
Эксперт С++
8379 / 6140 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.11.2012, 02:14 16
Ну если делал по статье форумской, то там какой-то нюанс с макросами, что точно не помню ...

Попробуй сделать по примеру из книги Архангельского.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.11.2012, 02:14
Помогаю со студенческими работами здесь

Уважаемые программисты, с опытом - загляните сюда пожалуста.
Здравствуйте. Программисты мне требуется помощ в онлайн. Если у кто-то может помоч, или есть...

Сложно объяснить,дело с :hover. Загляните внутрь
В общем, при наведение курсора на &quot;файл&quot;, то &quot;правка&quot; &quot;подъезжает&quot; к &quot;файлу&quot;. Помогите исправить....

Ошибка об отсутствии MSVCP140D.dll, ucrtbased.dll, CONCRT140D.dll, VCRUNTIME140D.dll
Добрый день, товарищи. Возникла проблема. Делаю программу с использованием openCV 3.1 на Visual...

Про два текстбокса (загляните на дусуге кто хочет)
Есть два текст бокса, в первом ввожу ip адрес, а во втором отображается тот же ip адрес но только в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru