Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
ВнизSTRING DLL Найти похожие ветки
← →
savyhinst © (2007-12-21 19:37) [0]Здраствуйте.
Как сделать ДЛЛ, чтобы в ней была функция, которая возвращает строку. Вроде, всё просто, но на мысли наталкивает текст в начале ДЛЛ типа нельзя пользоваться строками string без sharemem и borlandMM. Как обойтись без них?
Спасибо за внимание.
← →
Германн © (2007-12-21 19:39) [1]
> Как обойтись без них?
Забыть про String и использовать PChar.
← →
savyhinst © (2007-12-21 19:40) [2]А как корректно использовать PChar? Вроде там не всё гладко. Я вот, например, как-то пробовал...
← →
clickmaker © (2007-12-21 19:41) [3]
> Я вот, например, как-то пробовал...
я вот тоже как-то пробовал коньяк с пивом смешать... башка болела утром!
← →
savyhinst © (2007-12-21 19:46) [4]Ну это понятно. А как использовать PChar? Тут без ограничений?
← →
Германн © (2007-12-21 19:47) [5]
> Вроде там не всё гладко.
Нигде может быть не гладко, если руки кривые. Других проблем нет.
← →
savyhinst © (2007-12-21 19:49) [6]А можно создать работоспособную функцию, которая возвращает PChar?
← →
Германн © (2007-12-21 19:50) [7]
> А можно создать работоспособную функцию, которая возвращает
> PChar?
>
Можно. WinAPI просто завалена такими функциями.
← →
savyhinst © (2007-12-21 19:53) [8]А можно ещё маленький вопросик: как безопаснее сделать: передавать PChar или array of char?
← →
Германн © (2007-12-21 19:55) [9]А причем тут безопасность?
← →
savyhinst © (2007-12-21 19:59) [10]
> А причем тут безопасность?
Чтобы не возникало AcceessViolation att addrreess. Как это всегда бывает.
← →
Германн © (2007-12-21 20:01) [11]
> Чтобы не возникало AcceessViolation att addrreess. Как это
> всегда бывает.
Тогда без разницы что использовать. Результат то неизбежен. AV :)
← →
Григорьев Антон © (2007-12-21 20:39) [12]С WideString никаких проблем - просто берёшь и используешь без всяких ShareMem. Если не жалко терять время на перекодировку ANSI<->Unicode.
А проблема возникает не из-за строк самих по себе, а из-за того, что по умолчанию программа и DLL использует каждая свой менеджер памяти. И ошибки лезут тогда, когда один менеджер памяти пытается освободить то, что выделено другим менеджером. И с PChar будет та же проблема, если, скажем, StrNew вызвать в DLL, а StrDispose - в программе. Просто со string"ом эта проблема наименее предсказуема, так как не всегда очевидно, в какой именно момент будет предпринята попытка освободить память. ShareMem - это интерфейс к менеджеру памяти, который находится в borlndmm.dll. Если подключить ShareMem, то вместо обычного менеджера памяти будет использоваться этот, т.е. один и тот же и для приложения, и для DLL, и проблем, соответственно, не возникнет.
А в новых версиях Delphi есть ещё SimpleShareMem. Считайте, то же самое, только borlndmm.dll за собой таскать не надо. Суть в том, что там расшаривается менеджер памяти того модуля, который загрузился первым, а все остальные, кто подключил SimpleShareMem, вместо своего менеджера памяти будут использовать расшареный. Опять все пользуются оним менджером памяти, проблем нет.
Что же касается WideString, то для строк этого типа память выделяется специальным системным менджером памяти (через функции SysAllocString, SysFreeString и т.п.), и этот менеджер, естественно, один на весь процесс. Так что при использовании WideString вообще без разницы, подключен ShareMem или нет - всё равно дельфийский менеджер памяти не используется.
Но если вы твёрдо решили использовать PChar без ShareMem, для этого есть три варианта:
1. Программа заранее резервирует память для строки, передаёт в DLL указатель на эту память и размер блока, а DLL только заполняет эту строку символами, не перераспределяя память. Освобождается этот блок тоже в основной программе.
2. DLL выделяет память с помощю StrNew. Приложение только читает эту строку, но для освобождения памяти вызывает специальную функцию той же DLL, которая освобождает строку через StrDispose. Получается, что и выделяется, и освобождается память через один и тот же менеджер памяти DLL.
3. Использовать для выделения и освобождения памяти под строку тот же системный менеджер памяти, что и для WideString. Он доступен через функции CoTaskMemAlloc, CoTaskMemFree.
← →
savyhinst © (2007-12-21 20:41) [13]
> Григорьев Антон © (21.12.07 20:39) [12]
Спасибо за исчерпывающий комментарий.
← →
Sairex © (2007-12-22 11:11) [14]Ну можно и по другому сделать. Вот пример
Экзешник.
........................
Var P:PChar; S:String;
begin
S:="Мой текст!";
GetMem(P,1024);
lstrcpy(p,S);
MyProcDll(p);
ShowMessage(p);
FreeMem(P);
end;
Дллька.
library MyDll;
uses Windows,SysUtils,Classes; Dialogs;
procedure MyProcDll(P:PChar);
Var S:String; P:PChar;
begin
ShowMessage(P);
Lstrcpy(P,PChar("My Text..."));
end;
end.
Данный НАПИСАННЫЙ код я не проверял на работу. А так достаточно часто использую такой подход для передачи данных из\в длл.
Помоему эт реализация п.1
1. Программа заранее резервирует память для строки, передаёт в DLL указатель на эту память и размер блока, а DLL только заполняет эту строку символами, не перераспределяя память. Освобождается этот блок тоже в основной программе.
← →
DiamondShark © (2007-12-22 22:00) [15]
> GetMem(P,1024);
> lstrcpy(p,S);
> MyProcDll(p);
Вот так и появлятся программы, которые атакуются методом переполнения буфера.
← →
Dimaxx © (2007-12-23 11:41) [16]Используй ограниченный вариант string - shortstring.
← →
savyhinst © (2007-12-23 13:01) [17]Извините, конечно за мою тупость и неподточенность, но я вот понаделал тут, что мне посоветовали. И поначалу приходила пустота, а потом мною было решено: shortstring+stdcall - должно быть железно, как integer или smallint; это же сами данные, а не указатель на них, как string или PChar. И теперь не приходит ничего, и по исполнению процедуры приходит Access violation (read) in <Моя программа>. Что делать?
← →
Григорьев Антон © (2007-12-23 13:12) [18]
> savyhinst © (23.12.07 13:01) [17]
Вы такое выражение - "Ошибка в 17 строке" - слышали? Оно означает, что пока не будет показан код, сказать, где именно ошибка, невозможно. Так вот, у вас ошибка именно в этой строке.
← →
Германн © (2007-12-23 13:55) [19]
> а потом мною было решено: shortstring+stdcall - должно быть
> железно
Можно подумать что stdcall это волшебное слово. Стоит только его написать как сразу все заработает.
Кстати в том своем обрывочном примере в http://delphimaster.net/view/2-1198342227/ это слово не было упомянуто нигде. Так как прикажешь понимать тебя, Саид?
← →
savyhinst © (2007-12-23 14:17) [20]надеясь, что вы мне поможете:
library:
...
procedure SetMyDir(const _myDir:shortstring);
begin
myDir:=_myDir;
ShowMessage(myDir);
end;
...
exports
SetMyDir name "Effdll_setDllDirectory";
...
program:
...
type TSetDllIniProc=procedure(const ininame:shortstring);
...
var
iniDllnameProc:TSetDllIniProc;
libHandle:THandle;
str_libname:string;
shString:string;
begin
shString:=ini.FileName;
ShowMessage(shString); //ok
libHandle:=LoadLibrary(PAnsiChar(str_libname));
if libHandle=0 then raise exception.Create("Can"t load effects library");
@iniDllnameProc:=GetProcAddress(libHandle,cnst_setDllIniProcName);
if @iniDllNameProc=nil then raise exception.Create("Can"t load prefixProc");
iniDllnameProc(shString);
end;
← →
Германн © (2007-12-23 14:39) [21]Во-первых почему ты мешаешь string c shortstring?
Во-вторых где же все таки прячется тот самый stdcall?
← →
irish_34 (2007-12-23 17:39) [22]извините за вторжение, я наверное всех тут замучила, но можно спросить?
если всё работает но после сеанса работы возникает ошибка инструкция по памяти 0*00000000 обратилась к патяти по адресу 0*00000000, источник её такой же как ошибки AV?
← →
Sairex © (2007-12-24 15:43) [23]
> DiamondShark © (22.12.07 22:00) [15]
>
> > GetMem(P,1024);
> > lstrcpy(p,S);
> > MyProcDll(p);
>
> Вот так и появлятся программы, которые атакуются методом
> переполнения буфера.
Незнаю как у Вас но у меня все работает превосходно... И пока никто еще не жаловался на такую обшибку.
← →
Eraser © (2007-12-24 16:40) [24]
> Sairex © (24.12.07 15:43) [23]
> lstrcpy(p,S);
сюда можно передать стороку, которая длинее выделенного буффера, если правильно сформатировать эту строку, то можно выполнить произвольный код с правами вашего приложения.
← →
Сергей М. © (2007-12-25 11:06) [25]
> irish_34 (23.12.07 17:39) [22]
> источник её такой же как ошибки AV?
Это и есть AV.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.27;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.007 c