Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

DLL, весь день бошкой о стену бюсь... [D7, WinXP]


x.pro ©   (2005-12-15 00:43:00) 

Здравствуйте!

С библиотеками еще не сталкивался, практически ничего о них не знаю. Перечитал множество разных статей, какими обладал, но, увы, ответа не нашел. :(
Короче, задача такая. Есть главная форма (MainForm), есть библиотека (например, MyDLL), есть форма, пришитая к этой библиотеке (DllForm). Мне нужно, что бы брались данные из DllForm и передавались в MyDLL. а уже из MyDLL в MainForm.

Я пробовал таким образом, но без результатно. Где кроется ошибка?

library MyDLL;
uses
 SysUtils,Classes,Forms,Controls,
 formx in 'formx.pas' {DLLForm}

function RetResProg(): PChar; stdcall
var s: string;
begin
   DLLForm := TDLLForm.Create(Application);
   DLLForm.ShowModal;
   if DLLForm.ShowModal = mrOk then
   begin
           if DLLForm.Edit1.Text > '' then s := s + (DLLForm.Edit1.Text);
           if DLLForm.Edit2.Text > '' then s := s + (DLLForm.Edit2.Text);
           if DLLForm.Edit3.Text > '' then s := s + (DLLForm.Edit3.Text);
   end;
   result := pchar(s);
   DLLForm.Free;
end;
exports RetResProg;
{$R *.res}
begin
end.

дайте пожалуйста ссылку и приведите пример кода.
Спасибо!


DesWind   (2005-12-15 17:43:00) [1]


> x.pro   (15.12.05 17:06) [16]

У меня работает. ищи ошибку в другом месте. Отладчиком. А через файл обмениваться между приложением и библиотекой эт коряво как-то в твоем случае.


x.pro   (2005-12-15 17:42:00) [2]

Спасибо всем!


Morgoth_   (2005-12-15 17:28:00) [3]

для примера вот, сам где-то брал, под себя переделал немного:
GData - тип Record.

procedure OpenGlobalData;
begin
 // Пытаемся открыть объект файлового отображения в память (возможно он уже был создан)
 hMMF := OpenFileMapping(FILE_MAP_ALL_ACCESS, true, MMFName);
 if hMMF = 0 then  // если объект ещё не был создан
 begin
   { Создаём объект файлового отображения в память, значение INVALID_HANDLE_VALUE = -1 и говорит о том,
     что данные будут отображены в файл "подкачки" }
   hMMF := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TGlobalData), MMFName);
   if hMMF = 0 then
   begin
     MessageBox(0, 'Не удалось создать объект файлового отображения в память !!',
                'Error (OpenGlobalData -> CreateFileMapping)', MB_OK + MB_ICONERROR);
     DLLProc := nil;  
     HALT
   end
 end;
 { Отображаем глобальные данные на АП вызывающего процесса и
    получаем указатель на начало выделенного пространства }
 GData:= MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TGlobalData));
 if GData = nil then
 begin
   MessageBox(0, 'Не удалось отобразить глобальные данные на АП вызывающего процесса !!',
              'Error (OpenGlobalData -> MapViewOfFile', MB_OK + MB_ICONERROR);
   CloseHandle(hMMF);
   DLLProc := nil;  
   HALT
 end
end;

{--- Закрытие глобальных данных ---}
procedure CloseGlobalData;
begin
 if GData <> nil then
 begin
   UnmapViewOfFile(GData);  
   GData := nil
 end;
 if hMMF <> 0 then
 begin
   CloseHandle(hMMF);
   hMMF := 0
 end
end;


Morgoth_   (2005-12-15 17:25:00) [4]

данные из формы в файл. а при окончании работы библиотеки считывать из этого файла нужные данные

Существует, общую память используй, и храни там глобальные переменные.


x.pro   (2005-12-15 17:06:00) [5]

> DesWind ©   (15.12.05 16:59) [15]

Так, уже хорошо. AV не возникает. Только в диалоге основной программы все равно пусто.

У меня идея появилась, но ей я не особо хочу пользоваться, но наверное придется. Идея состоит вот в чем: записывать данные из формы в файл. а при окончании работы библиотеки считывать из этого файла нужные данные. Но может, все же, есть иной способ?


DesWind   (2005-12-15 16:59:00) [6]


> x.pro   (15.12.05 16:47) [14]

Если в библиотеке деректива stdcall, то и в остновной программе ее тоже надо посавить, паскалевский вызов отличается от стандартного.


x.pro   (2005-12-15 16:47:00) [7]

Так оно и есть! У меня ж ведь ShareMem стоит на первом месте.


umbra   (2005-12-15 16:42:00) [8]

ShareMem должен быть первым в uses модуля myproject.dpr


x.pro   (2005-12-15 16:30:00) [9]

> DesWind ©   (15.12.05 11:39) [11]

Вы это имели ввиду?

library MyDLL;
uses ShareMem, SysUtils, Classes,Forms,Controls,
 formx in 'formx.pas' {Form1};

function RetResProg(): String; stdcall
var s: string;
begin
   DllForm := TDllForm.Create(Application);
   DllForm.ShowModal;
   if DllForm.ShowModal = mrOk then
           result := DllForm.Edit1.Text+ DllForm.Edit2.Text+ DllForm.Edit3.Text;
   DllForm.Free;
end;
exports RetResProg;

{$R *.res}

begin
end.

И кусок основной программы:

...
uses ShareMem,...
...
procedure TMainForm.Button1Click(Sender: TObject);
var
   RetResProg: function: string;
begin
@RetResProg := nil;
   LibHandle := LoadLibrary('MyDll.dll');
   if LibHandle <> 0 then
   begin
       @RetResProg := GetProcAddress(LibHandle,'RetResProg');
           if @RetResProg <> nil then
           ShowMessage( RetResProg() );
   end else begin ShowMessage('Loading DLL failed...'); end;
 FreeLibrary(LibHandle);
end;


тогда av в ответ. Есть у кого нибудь толковая статья по написанию DLL? Или, может, реализация моей идеи должна осуществляться с помощью файлов?


DesWind   (2005-12-15 11:39:00) [10]

А кто под результат память будет выделять? Лучше уж добаить модуль ShareMem и пользовать тип string


umbra   (2005-12-15 11:38:00) [11]

2 wal ©   (15.12.05 11:36) [9]

да, точно. сам наконец-то до конца дочитал :)


wal   (2005-12-15 11:36:00) [12]

Незнаю, что у тебя за глюки, но первое, что бросается в глаза, это
result := pchar(s);
где s - локальная переменная, которая, мягко говоря, перестает существовать при выходе из функции.
> а Вы читали примечание в начале модуля MyDLL?
Если вы про ShareMem, то оно тут ни к чему.


umbra   (2005-12-15 11:30:00) [13]

а Вы читали примечание в начале модуля MyDLL?


x.pro   (2005-12-15 01:17:00) [14]

А если записать так:

if DLLForm.ShowModal = mrOk then
           result := PCHar(DLLForm.Edit1.Text+ DLLForm.Edit2.Text+ DLLForm.Edit3.Text);

то выводит в сообщении всякую абракадабру.


x.pro   (2005-12-15 01:13:00) [15]

Тю, Боже мой, простите, совсем вас запутал... Видимо перенапряжение сказывается. ~8-|

При выполнении программы. показывает пустой диалог, без всяких надписей.


x.pro   (2005-12-15 01:10:00) [16]

LibHandle: THandle; - глобальная переменная.


x.pro   (2005-12-15 01:09:00) [17]

Ага. Как при выполнении программы, показывает сообщение: "Loading DLL failed...". что я не так делаю?


x.pro   (2005-12-15 01:07:00) [18]

Ну не знаю. Если хотите, я приведу код и из MainForm. Может там чего не так....
вот он:

procedure TForm1.Button1Click(Sender: TObject);
var
   RetResProg: function: Pchar;
begin
@RetResProg := nil;
   LibHandle := LoadLibrary('MyDLL.dll');
   if LibHandle <> 0 then
   begin
       @RetResProg := GetProcAddress(LibHandle,'RetResProg');
           if @RetResProg <> nil then ShowMessage( StrPas(RetResProg()) );
   end
   else begin ShowMessage('Loading DLL failed...') end;
 FreeLibrary(LibHandle);
end;


а за какие мелкие баги вы говорили?


DrPass   (2005-12-15 00:57:00) [19]

И что не работает?
Сама по себе DLL написана правильно, если не считать мелких багов вроде работы с переменной s.


x.pro   (2005-12-15 00:46:00) [20]

дайте пожалуйста ссылку илиприведите пример кода.

А то уж многовато хочу.... ;)


Наверх

Титульная страница Поиск, карта сайта Написать письмо