Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
ВнизПередача и получение строк из DLL Найти похожие ветки
← →
dreamse (2006-11-23 19:54) [0]Приветсвую. Подскажите как нормально передавать строки в DLL и обратно
Подключение ShapeMem исключаеться так как неудобно
Через Pchar не получаеться, выдаёт какие то крякозябли :(
ShortString анологично - крякозабли ...
Подсказали передавать массив + размер массива а потом его востанавливать , но немогу разобраться как так как с массивами не работал нормально :(
← →
Джо © (2006-11-23 19:56) [1]> Через Pchar не получаеться, выдаёт какие то крякозябли :
> (
> ShortString анологично - крякозабли ...
Есть предложение — научиться передавать правильно, без кракозябликов.
← →
dreamse (2006-11-23 20:14) [2]> Джо © (23.11.06 19:56) [1]
Возможно :)
В чём ошщибка ?
EXE :
Function ApiGetPath:pchar; external "my.dll";
procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage(ApiGetPath);
end;
DLL
function ApiGetPath: Pchar; stdcall;
begin
result := Pchar("C:\1111\222\333");
end;
В ответ приходит либо крякозябли либо буква С :)
← →
Джо © (2006-11-23 21:36) [3]А посмотри, каковы способы передачи того-же PChar"а в функциях WinAPI. Суть в том, что PChar — это всего-лишь указатель на некую область памяти, в которой, предположительно, будет находиться нечто вроде "строки", т.е., печатаемые символы с завершающим символом с кодом 0.
Теперь смотри, что у тебя получается.
1. В функции ApiGetPath ты заводишь (неявно) константу-строку ("C:\1111...");
2. Приводишь ее к типу PChar.
3. Строки в Делфи — это объекты с управляемым временем жизни. Как только счетчик использования строки становится равным 0 (например, после выхода из функции, как у тебя), то этот объект разрушается.
4. Однако, адрес на эту область памяти ты возвращаешь в качестве результата функции. Повторяю, адрес, по которому строки уже нет.
Как поступать? Есть разные подходы, они отражены в WinAPI.
1. Выделяем память (динамически) под строку в самой функции. Возвращаем адрес на нее. Вызывающая программа, после того, как эта "строка" перестанет быть ей нужной, очищает память.function ApiGetPath: Pchar; stdcall;
const
S = "c:\123\456";
begin
GetMem (Result, Length(S));
StrCopy(Result,S)
end;
procedure TForm1.Button1Click(Sender: TObject);
var
P: PChar;
begin
P := ApiGetPath;
ShowMessage (P);
FreeMem(P);
end;
Довольно опасный подход, чреват утечкой памяти, потому что легко забыть освободить память.
2. Выделять память в основной программе и передавать указатель (PChar) на него в функцию, чтобы она записывала по этому адресу данные. Тонкость тут в чем? В том, что нужно заранее знать, сколько памяти выделить. Поступают обычно так: делают еще одну функцию, возвращающую размер, необходимый для хранения данных. В WinAPI это пара функций GetWindowTextLength/GetWindowText, используемых совместно. Второй подход: при передаче функции в кач-ве параметра nil она должна возвратить объем памяти, который ей необходим. После этого делается уже второй вызов, с указанием размера В WinAPI таких функций тоже немало.function ApiGetPath2 (P: PChar): Integer;
const
S = "c:\123\456";
begin
if P = nil then
Result := Length(S)
else
begin
StrCopy (P,S);
Result := 0;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
P: PChar;
N: Integer;
begin
N := ApiGetPath2(nil);
GetMem (P, N);
try
ApiGetPath2(P);
ShowMessage (P);
finally
FreeMem (P);
end;
end;
Преимущества — память выделяется и освобождается в одном месте. Недостатки — некоторая громоздкость.
Остальные способы — комбинации и вариации этих основных.
В таком аксепте, в общем, почитай хорошие книги :)
---
Писал это все в спешке, поэтому неисключены опечатки, ляпы, описки и просто грубые ошибки ;)
← →
dreamse (2006-11-23 22:23) [4]Спасибо конечно , буду разбираться. Но все кстати говорят что Pchar нормально передаёться ...
Когда передаю строку из DLL отлично принимаеться строка и всё ништяк.
Когде же передаю Строку в DLL то она приходит уже искажёная ... :(
EXE
procedure texts(value:pchar); external "Project1.dll";
procedure TForm1.Button1Click(Sender: TObject);
begin
texts(Pchar("123"));
end;
DLL
procedure texts(value:pchar); stdcall;
begin
Showmessage(StrPas(value));
end;
exports
texts;
Блин ... неужели нельзя просто передать строку блин в DLL ?
← →
dreamse (2006-11-23 22:32) [5]Буду возиться с памятью :)
← →
Desdechado © (2006-11-23 22:44) [6]и помни - соглашения о вызовах должны быть одинаковы для функции. Если она у тебя в DLL описана как stdcall, то и в вызывающей программе тоже должна
← →
Loginov Dmitry © (2006-11-23 23:25) [7]> Подключение ShapeMem исключаеться так как неудобно
Это что еще за монстр?
← →
dreamse (2006-11-23 23:31) [8]> Desdechado © (23.11.06 22:44) [6]
В этом то и была вся пробламма !! Спасибо !
Всем большое спасибо ! :)
← →
Leonid Troyanovsky © (2006-11-25 12:14) [9]
> dreamse (23.11.06 23:31) [8]
> > Desdechado © (23.11.06 22:44) [6]
> В этом то и была вся пробламма !! Спасибо !
Это вовсе не вся проблема.
Читать [3] до просветления.
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.12.10;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.045 c