C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
DLL, пример
Лена
Отправлено: 22.11.2006, 10:38


Мастер участка

Группа: Участник
Сообщений: 501



Впервые в жизни надо написать DLL. smile.gif
В DLL должна быть функция, которая принимал бы указатель на строку (char *). Далее эта функция просматривала бы определенную колонку в ClientDataset и если строка есть, то возвращала бы ее, а если нет, то возвращала бы NULL. Думаю что-то похожее уже должно существовать в качестве примера. Подскажите ссылку.
P.S.
Смутно представляю как в функции DLL получить доступ к ClientDataset приложения.
А если задача усложниться и надо будет получить доступ к полю которое храниться в базе на удаленном сервере, то тогда вообще не понятно как такое реализовать. wizard.gif

Отредактировано Лена — 22.11.2006, 11:05
exp
Отправлено: 22.11.2006, 11:57


Мастер участка

Группа: Участник
Сообщений: 304



примерчик в аттаче.

User Attached Image Скачать файл
DLL.zip


olegenty
Отправлено: 22.11.2006, 12:27


Ветеран

Группа: Модератор
Сообщений: 2412



Лиха беда начало. Я уже скоро забуду, что такое EXE: запускающий модуль практически не меняется около года, а весь функционал давно в DLL.
Лена
Отправлено: 22.11.2006, 12:49


Мастер участка

Группа: Участник
Сообщений: 501



Создала DLL и h файл к ней, теперь добавила модуль данных для связи с базой и добавила в него h файл dll.
Правильной дорогой иду? rolleyes.gif
Лена
Отправлено: 22.11.2006, 13:12


Мастер участка

Группа: Участник
Сообщений: 501



В DLL у меня пока так:
CODE

#pragma argsused
#include "UFind.h" //h файл DLL
#include "UDataModule.h"  //Дата модуль
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
       return 1;
}
//---------------------------------------------------------------------------

char * FindRecord(char *s)
{
//тут искать запись
return s;
}


В UFind.h так:
CODE

#ifndef  _UFIND_H
#define  _UFIND_H

#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else
#define DLL_EI __declspec(dllimport)
#endif

extern "C" char * DLL_EI FindRecord(char *s);
#endif


Правильно?
AVC
Отправлено: 22.11.2006, 13:59


Ветеран

Группа: Модератор
Сообщений: 1583



Датамодуль в отдельный пакет(dll) и использовать его в exe и прочих пакетах. В него включаются сессия и базовые функции для работы с базой. Наборы данных создает каждый пакет у себя по мере надобности.
Лена
Отправлено: 22.11.2006, 17:43


Мастер участка

Группа: Участник
Сообщений: 501



Код в DLL такой:
CODE

#pragma argsused
#include "UFind.h" //h файл DLL
#include "UDataModule.h"  //Дата модуль
#include <stdio.h>

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
       return 1;
}
//---------------------------------------------------------------------------

char buf[1024];

char * FindRecord(char *param)
{

 int Test = 0; //сразу исключение

 DataModule1->ADOQuery1->Active = false;
 DataModule1->ADOQuery1->SQL->Clear();
 sprintf(buf, "select code from key where code = \"%s\"", param);
 DataModule1->ADOQuery1->SQL->Text = String(buf);
 DataModule1->ADOQuery1->Active = true;
 char *res = NULL;
 if (DataModule1->ADOQuery1->RecordCount == 0)
  ; // ничего не делать вообще
 else {
       res = new char[DataModule1->ADOQuery1->FieldByName("code")->AsString.Length() + 1];
       strcpy(res, DataModule1->ADOQuery1->FieldByName("code")->AsString.c_str());
      }
   DataModule1->ADOQuery1->Active = false;
   return res;

}



Создала тестовое приложение. Добавила в него lib файл. Код тестового приложения:
CODE

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "UFind.h" //DLL
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->Text = FindRecord(Edit1->Text.c_str());
}
//---------------------------------------------------------------------------


При нажатии на кнопку получаю исключение на первой же строке FindRecord

Присоединить изображение

Присоединить изображение

olegenty
Отправлено: 22.11.2006, 17:57


Ветеран

Группа: Модератор
Сообщений: 2412



в отладчик и разбираться.
Лена
Отправлено: 22.11.2006, 18:21


Мастер участка

Группа: Участник
Сообщений: 501



Мне кажется, что Дата Модуль просто не создается, хоть он и есть в DLL.
olegenty
Отправлено: 22.11.2006, 18:24


Ветеран

Группа: Модератор
Сообщений: 2412



автоматически в DLL НИЧЕГО не создаётся. всё надо делать руками. и создавать, и удалять. вариантов комбинаций много, но лично я предпочитаю, чтобы за выдеоение и освобождение памяти отвечала DLL, а управлял этим процессом EXE.
Лена
Отправлено: 22.11.2006, 18:28


Мастер участка

Группа: Участник
Сообщений: 501



Где создовать в коде Дата Модуль? А компонеты которые лежат на Дата Модуле типа ADOquery, тоже создовать надо?
olegenty
Отправлено: 22.11.2006, 18:31


Ветеран

Группа: Модератор
Сообщений: 2412



нет, достаточно создать DataModule.

ну, помимо того, что в DLL выполнится какая-то функция, надо вызвать, например, Prepare — которая создать модуль данных. затем — твою целевую функцию, а затем Free — которая освободит ресурсы. Prepare и Free тебе также надо разработать самой и также экспортировать из DLL. затем, сразу после LoadLibrary вызываешь Prepare, потом делаешь всё, что угодно, и перед FreeLibrary вызываешь Free.
Лена
Отправлено: 22.11.2006, 18:42


Мастер участка

Группа: Участник
Сообщений: 501



Теперь понятно. Сложное это дело DLL wizard.gif smile.gif
olegenty
Отправлено: 22.11.2006, 18:46


Ветеран

Группа: Модератор
Сообщений: 2412



не-а, как я раньше без них жил — ума не приложу. с ними намного упрощается
1. процесс разработки (при наличии внутреннего стандарта, хотябы интерфейса вызова. у меня каждая DLL экспортирует всего по 2 функции. Плагины — Execute и Free, Аддоны — Register и Unregister).
2. процесс сопровождения
Лена
Отправлено: 22.11.2006, 19:03


Мастер участка

Группа: Участник
Сообщений: 501



Почему простой путь не правильный?
CODE

char * FindRecord(char *param)
{

TDataModule1 * DataModule1 = new TDataModule1(Application);
DataModule1->ADOQuery1->Active = false;
DataModule1->ADOQuery1->SQL->Clear();
sprintf(buf, "select code from key where code = \"%s\"", param);
DataModule1->ADOQuery1->SQL->Text = String(buf);
DataModule1->ADOQuery1->Active = true;
char *res = NULL;
if (DataModule1->ADOQuery1->RecordCount == 0)
;
else {
res = new char[DataModule1->ADOQuery1->FieldByName("code")->AsString.Length() + 1];
strcpy(res, DataModule1->ADOQuery1->FieldByName("code")->AsString.c_str());
}
DataModule1->ADOQuery1->Active = false;
char *res2 = res;
delete res;
delete DataModule1;
return res2;

}


то ошибка на рисунке:
и курсор поподает сюда:
__fastcall TDataModule1::TDataModule1(TComponent* Owner)
: TDataModule(Owner)
{
}

Отредактировано Лена — 22.11.2006, 19:18
Лена
Отправлено: 22.11.2006, 19:18


Мастер участка

Группа: Участник
Сообщений: 501



рис

Присоединить изображение

Присоединить изображение

Лена
Отправлено: 22.11.2006, 19:42


Мастер участка

Группа: Участник
Сообщений: 501



У меня заработал такой вариант. Надежно так?
CODE

char * FindRecord(char *param)
{
CoInitialize(NULL);
TDataModule1 * DataModule1 = new TDataModule1(Application);
DataModule1->ADOQuery1->Active = false;
DataModule1->ADOQuery1->SQL->Clear();
sprintf(buf, "select code from keys where code = '%s'", param);
DataModule1->ADOQuery1->SQL->Text = String(buf);
DataModule1->ADOQuery1->Active = true;
char *res = NULL;
char *res2 = NULL;
if (DataModule1->ADOQuery1->RecordCount == 0)
; // ничего не делать
else {
res = new char[DataModule1->ADOQuery1->FieldByName("code")->AsString.Length() + 1];
strcpy(res, DataModule1->ADOQuery1->FieldByName("code")->AsString.c_str());
res2 = strcpy(buf,res);

delete res;
}
DataModule1->ADOQuery1->Active = false;
delete DataModule1;
CoUninitialize();//это надо?
return res2;

}


Отредактировано Лена — 22.11.2006, 20:04

Вернуться в Вопросы программирования в C++Builder