Форум: "Начинающим";
Текущий архив: 2006.01.01;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.012 c