Создание dll библиотеки и её динамическое подключение....
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Подскажите плиз, у меня такой вопрос, что-то не могу найти на него ответ: :?:
Мне необходимо с помощью C++ Builder создать динамическую dll библиотеку со своей функцией. А затем, чтобы в программе, уже откомпелированной (exe-шнике) мог ввести путьк ней и эта библиотека бы подключилась и я мог использовать функцию описанную ней...
Подскажите, буду очень признателен...
Мне необходимо с помощью C++ Builder создать динамическую dll библиотеку со своей функцией. А затем, чтобы в программе, уже откомпелированной (exe-шнике) мог ввести путьк ней и эта библиотека бы подключилась и я мог использовать функцию описанную ней...
Подскажите, буду очень признателен...
-
- Сообщения: 38
- Зарегистрирован: 21 июн 2004, 02:59
- Откуда: Saratov
- Контактная информация:
Что значит фраза
:?:Mike_3000 писал(а):А затем, чтобы в программе, уже откомпелированной (exe-шнике) мог ввести путьк ней и эта библиотека бы подключилась и я мог использовать функцию описанную ней...
Mike_3000, опиши подробнее ситуацию. В exe-шнике подразумевается динамическое подключение DLL (c помощью LoadLibrary)?
Извените, видимо действительно на полностью изложил ситуацию. Я только начал писать на C++, и мне надо написать программу, в которой будут использоваться функции которые должны быть записаны в dll. Т.е. в рабочем состоянии (exe-шнике) есть кнопка, в которой открываеться OpenDialog и я выбираю путь к dll-ке которую надо подключить. 

В чём конкретно твоя проблема?
а. Создание DLL-модуля?
б. Его загрузка из приложения?
в. Вызов стандартного окна диалога?
Или ещё что-то?
а. Создание DLL-модуля?
б. Его загрузка из приложения?
в. Вызов стандартного окна диалога?
Или ещё что-то?
1) Создай DLL с помощью DLL Wizard, начини ее своими функциями и объяви их экспортируемыми (как это сделать, см. ссылку в конце поста).
2) На форму положи кнопку Load и компонент типа TOpenDialog.
3) Определи глоб.переменную для дескриптора загружаемой библиотеки:
3) Задай для кнопки обработчик:
4) Теперь, если DLL удалось загрузить, можно вызывать экспортируемые ею функции. Примерно так:
5) Когда DLL больше не нужна, выгружаем ее из памяти:
В общем, схема примерно такая. Вот еще ссылка, там изложено подробнее: http://v3ps.narod.ru/ru/programming/cpp ... create.htm
2) На форму положи кнопку Load и компонент типа TOpenDialog.
3) Определи глоб.переменную для дескриптора загружаемой библиотеки:
Код: Выделить всё
HMODULE gLib;
Код: Выделить всё
void __fastcall TForm1::LoadClick(TObject *Sender)
{
OpenDialog1->DefaultExt = "DLL";
OpenDialog1->FileName = "*.dll";
OpenDialog1->Filter = "Dynamic-link libraries|*.DLL";
// C помощью станд.диалога Open находим нужную DLL
if (OpenDialog1->Execute())
{
// Пытаемся загрузить ее
gLib = LoadLibrary(OpenDialog1->FileName);
if (!gLib)
MyErrorHandler();// сообщаем об ошибке
}
}
Код: Выделить всё
// Предположим, что в DLL есть такая функция: String _declspec(dllexport) __stdcall HelloFunc(void) { return "Hello, buddy!"; }
typedef String __stdcall (*MySimpleFunc)(void);
...
// Динамический вызов:
MySimpleFunc func;
if (gLib)
{
func = (MySimpleFunc)GetProcAddress(gLib,"_HelloFunc"); // Зам.: С++ Builder добавляет подчеркивание в имена всех экспортируемых функций
if (func) // если есть такая функция в загруженной DLL
Label1->Caption = func(); // вызываем ее
}
Код: Выделить всё
FreeLibrary(gLib);
Пасиб отчасти помогло, но всё равно до конца не получаеться:
поступаю таким образом
Создаю dll в С++
файл rmn.cpp:
содеражание rmn.h
Нажимаю Build, библиотеку делает всё впорядке, а вот терь пытаюсь подключить библиотечку и использовать функцию:
пишу :
В заголовочном файле прописано
Dll подключает а функцию не видит. ПОдскажите, плз, что я не так делаю
поступаю таким образом
Создаю dll в С++
файл rmn.cpp:
Код: Выделить всё
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
switch(fwdreason)
{
case DLL_PROCESS_ATTACH:
if(lpvReserved)
MessageBox(NULL, "Ïðîöåññ ïîäêëþ÷èë DLL ñòàòè÷åñêè", "DLLMain", MB_OK);
else
MessageBox(NULL, "Ïðîöåññ ïîäêëþ÷èë DLL äèíàìè÷åñêè", "DLLMain", MB_OK);
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, "Ïðîöåññ îòêëþ÷èë DLL", "DLLMain", MB_OK);
break;
case DLL_THREAD_ATTACH:
MessageBox(NULL, "Òðýéä ïîäêëþ÷èë DLL ñòàòè÷åñêè", "DLLMain", MB_OK);
break;
case DLL_THREAD_DETACH:
MessageBox(NULL, "Òðýéä îòêëþ÷èë DLL", "DLLMain", MB_OK);
break;
}
return 1;
}
float MyFunc(float x)
{
float y = 0;
y = x*x;
return y;
}
Код: Выделить всё
#ifndef __RMN_H
#define __RMN_H
#if defined(__cplusplus)
extern "C"
{
#endif
__declspec(dllexport) float MyFunc(float x);
#if defined(__cplusplus)
}
#endif
#endif //__RMN_H
пишу :
Код: Выделить всё
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HMODULE gLib;
MySimpleFunc func;
gLib = LoadLibrary("rmn.dll");
if (gLib)
{
func = (MySimpleFunc)GetProcAddress(gLib,"_MyFunc");
if (func)
Label1->Caption = FloatToStr(func(2)); }
}
В заголовочном файле прописано
Код: Выделить всё
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
//---------------------------------------------------------------------------
typedef float __stdcall (*MySimpleFunc)(float);
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TButton *Button1;
TLabel *Label1;
TButton *Button2;
TOpenDialog *OpenDialog1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
HINSTANCE DllHandle;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Dll подключает а функцию не видит. ПОдскажите, плз, что я не так делаю

Воспользуйся утилитой impdef.exe из $(BCB)\Bin (она строит .def-файл для dll) и посмотри имя экспортируемой функции. Синтаксис impdef.exe rmn.def rmn.dll, примерный вид .def-файла:
Здесь вместо MyFunc может стоять _MyFunc или что-то еще - это экспортируемое имя твоей функции (а @1 - ее порядковый номер, можно обращаться и по нему). Это имя и нужно передать в GetProcAddress().
Можно сделать проще: опиши прототип своей функции (в RMN.H):
- тогда экспортируемое имя будет просто "MyFunc", без дополнительных украшений.
Но советую все же разбраться, как работать с DLL, что такое статическая и динамическая загрузка - пригодится в дальнейшей программерской работе/учебе
На RSDN есть хорошая статья по DLL http://www.rsdn.ru/article/devtools/bcbdll.xml
И пусть "прикладное" название не смущает, там вопрос рассмотрен достаточно широко.
Код: Выделить всё
LIBRARY RMN.DLL
EXPORTS
MyFunс @1 ;
Можно сделать проще: опиши прототип своей функции (в RMN.H):
Код: Выделить всё
extern "C"
{
float __declspec(dllexport) __stdcall MyFunc(float x);
}
Но советую все же разбраться, как работать с DLL, что такое статическая и динамическая загрузка - пригодится в дальнейшей программерской работе/учебе

И пусть "прикладное" название не смущает, там вопрос рассмотрен достаточно широко.