![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Я понимаю что подобное уже не раз спрашивали, но все же...
kull © (2002-10-28 18:51:00)Как передать строку (PChar) из Dll. Что бы вызывающее приложение могло ее кничтожить?
Я делаю так:
в dll-ке
....
function GetSubject: PChar; cdecl;....
begin
Result := StrNew("subject");
end;
exports GetSubject;
в приложении
......
procedure TForm1.Button1Click(Sender: TObject);
var
H: HMODULE;
fn: function: PChar; cdecl;
S: PChar;
begin
H := LoadLibrary("d:\MyDLL.dll");
fn := GetProcAddress(H, "GetSubject");
S := fn;
StrDispose(S);//Вот здесь валится с сообщением "Invalid pointer operation"
end;
Помогите идиоту, что-то я под вечер совсем не соображаю.
Digitman (2002-10-29 15:56:00) [1]>AlexKniga
Не хватало мне еще сыщиком работать)
AlexKniga (2002-10-29 15:46:00) [2]2 Digitman
reonid = Le Taon = 195.9.0.43
Digitman (2002-10-29 14:30:00) [3]>reonid
А где и что именно ты"имел ввиду" ? Свое возражение я, кажется, адресовал <Le Taon (29.10.02 14:05)>
> через три глобальные функции, помещёных в структуру
Ну и что ? Хост-процесс вполне может иметь свою структуру, а DLL - свою.
reonid (2002-10-29 14:23:00) [4]2Digitman ©
Я имел в виду не внутреннюю реализацию менеджера памяти,
а то, что доступ к нему производится через три глобальные функции, помещёных в структуру. Поэтому не должно быть проблем
с РТТИ и всего прочих сопутствующих явлений, связанных с
передачей объектов в ДЛЛ.
Digitman (2002-10-29 14:16:00) [5]>Le Taon
>>Менеджер памяти - не объект, а структура
Именно объект, а не просто структура. Ибо со структурами, создаваемыми и поддерживаемыми конкретным менеджером, всегда ассоциирован код, выполняющий преобразования подконтрольных ему структур. Иными словами - единство данных и кода (осуществляющего некие действия над этими данными) есть суть представления менеджера именно как объекта.
Digitman (2002-10-29 14:09:00) [6]
> Вот я и работаю с памятью с помощью VirtualAlloc и VirtualFree...
Если уж на то пошло, то работать нужно не с сист.менеджером вирт.памяти непосредственно, а с менеджером кучи (см. HeapAlloc, HeapRealloc, HeapFree). Это - наипростейший базовый менджер памяти системы, специально предназначенный для манипуляций с программной памятью на уровне прикладного кода, не озадаченного всякого рода спецификой страничного режима. Для всех прикладных задач достаточно того факта, что с сответствующим процессом при его инициализации система всегда ассоциирует индивидуальный хип, хэндл которого в любой момент времени можно получить вызовом GetProcessHeap. В системный хип-менеджер же инкапсулированы ф-ции распределения ВАП процессов (те самые, но неявно вызываемые VirtualAlloc/Realloc/Free)
kull (2002-10-29 14:05:00) [7]
> Юрий Федоров © (29.10.02 13:59)
Да мне кажется CallBack все же то что надо.
Le Taon (2002-10-29 14:05:00) [8]Можно просто передать менеджер памяти из ЕХЕ в ДЛЛ.
(через GetMemoryManager/SetMemoryManager)
Менеджер памяти - не объект, а структура, поэтому никаких
побочных эффектов возникнуть не должно.
(А ShareMem я как-то не доверяю)
Игорь Шевченко (2002-10-29 14:02:00) [9]HeapAlloc, HeapFree к примеру.
ShareMem подойдет, если и приложение и DLL написано на Delphi или (не проверялось) на Delphi и C++ Builder.
Юрий Федоров (2002-10-29 13:59:00) [10]ИМХО, если действительно необходимо выделять память в одном месте,а освобождать в другом, решения два:
1. передача Callback
2. использование ShareMem
Le Taon (2002-10-29 13:56:00) [11]2kull ©
>Вот я и работаю с памятью с помощью VirtualAlloc и VirtualFree...
VirtualAlloc предназначена для выделения памяти большими кусками, наименьший размер выделяемой памяти - страница.
(При этом ещё резервируется 64К адресного пространства).
Не слишком ли много на одну строку???
Digitman (2002-10-29 13:50:00) [12]и к чему такие сложности ?
Здесь важно понять, что менеджер памяти Delphi по-умолчанию, доступ к которому осуществляется (явно или неявно) через вызовы SysAllocMem/SysReallocMem/SysFreeMem, "живет" в модуле system.pas. Если ты не контролируешь в каждый момент, сколько экз-ров менеджера существует в твоем процессе, то и получаешь соответствующую проблему. Модули в составе DLL обращаются за выделением/перераспределением памяти к своему экземпляру, а хост-процесс - к своему, когда от него требуют освободить блок памяти по ссылке. Но ссылка, созданная одним экземпляром, ничего не значит для другого ! Разные экз-ры одного и того же менеджера ничего не знают друг о друге !
kull (2002-10-29 13:38:00) [13]
> Digitman © (29.10.02 13:18)
Вот я и работаю с памятью с помощью VirtualAlloc и VirtualFree...
Digitman (2002-10-29 13:18:00) [14]Простой и наглядный пример : механизм использования UDF в ядре IB-сервера в таких случаях требует от кода в составе UDF DLL выделения/перерераспределения блоков памяти с использованием менеджера в составе msvcrt.dll. Если UDF успешно выделила память (malloc/realloc)и возвратила ссылку на нее, то вызыв.код в составе хост-процесса IB-сервера успешно освободит ее (free), имея возвращенную ссылку и соотв.указание в декларации UDF
Digitman (2002-10-29 13:10:00) [15]Если используется единый (для вызывающего и вызываемого модулей) объект, реализующий ф-ции менеджера памяти, никаких проблем со взаимодействием модулей (по сабжу вопроса) нет и быть не должно.
VaS (2002-10-29 12:50:00) [16]panov:
for i := 0 to 1022 do tPChar[i] := "$";
проще так
FillChar(tPChar^, 1023, "$");
kull (2002-10-29 11:32:00) [17]Thanks!
panov (2002-10-29 11:09:00) [18]>kull © (29.10.02 11:03)
Угу, можно CallBack...
У меня получалось функции из DLL для методов TThread так использовать...
kull (2002-10-29 11:03:00) [19]
>
> panov © (29.10.02 09:36)
Неплохое решение, а еще можно в вызываемую процедуру указатель на функцию которая выделяет память. Что-то типа CallBack-a... :)
kull (2002-10-29 11:00:00) [20]
> Юрий Зотов © (29.10.02 08:52)
> PChar - он и есть PChar, все равно в конце строки будет
> ноль. Так что никаких дополнительных функций не требуется
> - длина строки определяется автоматически.
Это понятно, но как вызывающая сторона определит какого размера буфер нужно выделить, когда неизвестна длина строки?