Приветствую всех!
Как правильно написать экпортируемую функцию, которая использует в качестве параметра
объект типа TStringList ( myfunc(v1:TStringList) )? Я пишу программу, а к ней — дополнения
в виде DLL. Ну и при вызове таких функций из динамически загрузаемых, по мере надобности, DLL
возникают всякие исключительные состояния, т.к. эти функции изменяют сами строки.
Я добавил в список используемых библиотек основной программы и DLL sharemem,
но все стало еще хуже, т.к. теперь при попытке выгрузить библиотеку,
использующую sharemem и загруженную командой loadlibrary (я применяю динамическую загрузку),
при помощи команды freelibrary мне выдается сообщение EInvalidPointerOperation.
Чего делать-то? Неохото мне все переписывать под shortstring и PChar! Тем более что
все остальное таким образом и передается, проблема с TStringList. Самое интересное,
что у меня есть другая программа, к которой прилагаются тексты plugins, а в них есть экспортируемые
функции с параметрами типа TStringList, но в списке Uses там только Windows, Classes, SysUtils,
нет никакой sharemem! Правда мне не известно, как сама программа написана, но библиотеку
sharemem она также нe использует! (Доподлинно известно, что программа написана на Delphi.)
Я использую Delphi-6/W2K-SP5.
Заранее спасибо!
Re: Параметр типа TStringList в экпортируемой функции
Я бы с большим интересном понаблюдал за попытками дать разумный ответ на вопрос — нахрена ее выгружать.
G>написана, но библиотеку sharemem она также нe использует!
А есть такая библиотека?
Re: Параметр типа TStringList в экпортируемой функции
-- Первым делом убедись что юнит ShareMem являеется певым модулем в библиотеке.
-- Программа загружающая плагины тоже должна иметь ShareMem.pas первым юнитом в проэкте.
Это необходимо для того чтобы никакой другой юнит имеющий секцию инициализации
не выделил память до того как ShareMem.pas проинициализирует менеджер памяти.
Если это не так — EInvalidPointerOperation гарантируется.
Программа:
program MyProgram;
uses
ShareMem,
Forms,
...
Плагин:
library Plugin;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
ShareMem,
SysUtils,
Classes;
......
Все дело в том что необходимо сделать так что бы память выделяемая библиотекой и твоей программой
принадлежала одному менеджеру памяти. Это достигатся путем подключения дополнительной библиотеки borlandmm.dll.
Тоесть когда ты подключаеш Sharemem.pas — то программа подгружает borlandmm.dll.
Когда ты стартуеш свой плагин он подгружает ту же dll с тем же адресным пространством.
Тоесть плагин и программа будут иметь загруженную dll c теми же глобальными переменными,
в нашем случае — менеджером памяти, чего и следовало добится.
И еще раз: проверь что твоя программа и DLL имеет Sharemem.pas первым юнитом в проэкте, это важно...
Удачи!
Re[2]: Параметр типа TStringList в экпортируемой функции
Здравствуйте, Softwarer, Вы писали:
S>Здравствуйте, greyvger, Вы писали:
S>http://softwarer.ru/packages.html
G>>но все стало еще хуже, т.к. теперь при попытке выгрузить библиотеку,
S>Я бы с большим интересном понаблюдал за попытками дать разумный ответ на вопрос — нахрена ее выгружать.
Так надо. Я вообще-то сам придумал этот способ, но оказалось, что так и делают.
См. советы по Delphi от Валентина Озерова 1.4.6 от 01.04.2001 DLL->разное->как работать с плагинами.
Только у меня немного по другому, потому что так надо.
G>>написана, но библиотеку sharemem она также нe использует!
S>А есть такая библиотека?
См. описание/назначение sharemem в справке к Delphi.
Re[2]: Параметр типа TStringList в экпортируемой функции
Здравствуйте, Danchik, Вы писали:
D>-- Первым делом убедись что юнит ShareMem являеется певым модулем в библиотеке. D>-- Программа загружающая плагины тоже должна иметь ShareMem.pas первым юнитом в проэкте.
Все так и есть, справку я уже читал.
Буду думать...
Re[2]: Параметр типа TStringList в экпортируемой функции
Здравствуйте, Danchik, Вы писали:
D>-- Первым делом убедись что юнит ShareMem являеется певым модулем в библиотеке. D>-- Программа загружающая плагины тоже должна иметь ShareMem.pas первым юнитом в проэкте.
Все так и есть. Но все равно возникают ошибки.
Буду думать.
Re[3]: Параметр типа TStringList в экпортируемой функции
Здравствуйте, greyvger, Вы писали:
S>>Я бы с большим интересном понаблюдал за попытками дать разумный ответ на вопрос — нахрена ее выгружать.
G>Так надо. Я вообще-то сам придумал этот способ, но оказалось, что так и делают.
G>См. советы по Delphi от Валентина Озерова 1.4.6 от 01.04.2001
Посмотрел оглавление. Первое, на что наткнулся — совет, за который программиста надо гнать ссаными тряпками (в начале программы делать DecimalSeparator := '.').
DLL->разное->как работать с плагинами.
Посмотрел. Не нашел там такой глупости, как выгрузка плагина после использования. Само решение — не фонтан, но приемлимо.
G>>>написана, но библиотеку sharemem она также нe использует! S>>А есть такая библиотека? G>См. описание/назначение sharemem в справке к Delphi.
Посмотри тогда уж и словарик, что ли.
Re: Параметр типа TStringList в экпортируемой функции
Здравствуйте, greyvger, Вы писали:
G>Приветствую всех! G>Как правильно написать экпортируемую функцию, которая использует в качестве параметра G>объект типа TStringList ( myfunc(v1:TStringList) )? Я пишу программу, а к ней — дополнения G>в виде DLL. Ну и при вызове таких функций из динамически загрузаемых, по мере надобности, DLL G>возникают всякие исключительные состояния, т.к. эти функции изменяют сами строки. G>Я добавил в список используемых библиотек основной программы и DLL sharemem, G>но все стало еще хуже, т.к. теперь при попытке выгрузить библиотеку, G>использующую sharemem и загруженную командой loadlibrary (я применяю динамическую загрузку), G>при помощи команды freelibrary мне выдается сообщение EInvalidPointerOperation. G>Чего делать-то? Неохото мне все переписывать под shortstring и PChar! Тем более что G>все остальное таким образом и передается, проблема с TStringList. Самое интересное, G>что у меня есть другая программа, к которой прилагаются тексты plugins, а в них есть экспортируемые G>функции с параметрами типа TStringList, но в списке Uses там только Windows, Classes, SysUtils, G>нет никакой sharemem! Правда мне не известно, как сама программа написана, но библиотеку G>sharemem она также нe использует! (Доподлинно известно, что программа написана на Delphi.) G>Я использую Delphi-6/W2K-SP5. G>Заранее спасибо!
Используй Packages