Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.01.01;
Скачать: CL | DM;

Вниз

DLL, весь день бошкой о стену бюсь...   Найти похожие ветки 

 
x.pro   (2005-12-15 00:43) [0]

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

С библиотеками еще не сталкивался, практически ничего о них не знаю. Перечитал множество разных статей, какими обладал, но, увы, ответа не нашел. :(
Короче, задача такая. Есть главная форма (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.

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


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

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

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


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

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


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

Ну не знаю. Если хотите, я приведу код и из 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;


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


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

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


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

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


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

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

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


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

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

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

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


 
umbra ©   (2005-12-15 11:30) [8]

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


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

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


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

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

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


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

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


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

> 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? Или, может, реализация моей идеи должна осуществляться с помощью файлов?


 
umbra ©   (2005-12-15 16:42) [13]

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


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

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


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


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

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


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

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

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

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


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

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

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


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

для примера вот, сам где-то брал, под себя переделал немного:
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;


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

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


 
DesWind ©   (2005-12-15 17:43) [20]


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

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



Страницы: 1 вся ветка

Текущий архив: 2006.01.01;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.051 c
1-1133555059
SergProger
2005-12-02 23:24
2006.01.01
Проверка Буфера


14-1133945876
NeverL8
2005-12-07 11:57
2006.01.01
Подскажите нормальные, бесплатные компоненты для работы с TWAIN


2-1134831588
shoni
2005-12-17 17:59
2006.01.01
Как изменить цвет фона Memo1?


14-1133737708
Kerk
2005-12-05 02:08
2006.01.01
Вывести числа от 1 до 100 без циклов и условий


1-1133515793
VID
2005-12-02 12:29
2006.01.01
Проблема отрисовки ProgressBar в XP !