Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.29;
Скачать: CL | DM;

Вниз

DLL   Найти похожие ветки 

 
Konsul   (2004-08-02 08:53) [0]

Здравствуйте, уважаемые мастера!
У меня возникла такая проблема, с которй сталкивается, наверное, каждый начинающий в области dll.
Проблема вот в чём. Задаю в dll функцию, возвращающую значение string. Сама программа работает с dll следующим образом:
задаём переменные:
type TGetStr=function: string; stdcall;
var
Hinst: THandle;
FPointer: TFarProc;
GetStr: TGetStr;
s: string;


Затем выполняем слeдующие действия:
HInst:=LoadLibrary(PChar("test_dll.dll"));
if HInst<=0 then begin messagedlg("DLL глючит!",mtError,[mbOk],0); exit; end;
FPointer:=GetProcAddress(Hinst,PChar("GetStr"));
if FPointer<>nil then
begin
GetStr:=TGetStr(FPointer);
s:=GetStr;
end;


если в самой dll возвращяемое значение задать прямым значением или переменой, относящейся к данной функции, т.е.

function GetStr: string; stdcall;
begin
result:="Test string!";
end;


то прога получает это значение, но потом пишет ошибку EInvalidPointer with message "Invalid Pointer operation". Но если задать result так:

function GetStr: string; stdcall;
begin
result:=s;
end;


где s - более глобальная переменна, значение которой задаётся какой-либо другой процедурой, то никаких ошибок нет. Странно!...
Мастера, помогите разобраться, в чём дело! Заранее благодарен!


 
xShadow ©   (2004-08-02 09:00) [1]

Dll не может возвращать String только PChar


 
Думкин ©   (2004-08-02 09:00) [2]

А ты пробовал читать комментарий вверху dll, когда был создан ее юнит. Он не только для красоты.


 
Рамиль ©   (2004-08-02 09:18) [3]


> Dll не может возвращать String только PChar

Может.


 
Digitman ©   (2004-08-02 09:40) [4]


> более глобальная переменна


интересные, однако, нововведения)

оказывается "глобальность" переменной отныне можно оценивать на качественном уровне : "больше глобальности" или "меньше глобальности"


 
Konsul   (2004-08-05 09:15) [5]

> более глобальная переменна
Я имею ввиду, что объявленная на уровне всей dll.


 
Digitman ©   (2004-08-05 09:18) [6]


> Konsul


собери оба проекта с опцией Build With Run-Time Packages


 
Юра   (2004-08-05 09:49) [7]

Правильно сказал Думкин.
Трабл заключается в том, что ДЛЛ использует свой менеджер памяти а exeшник свой. Выделение памяти под стринг происходит в длл, а удаление в ЕХЕ. Вот здесь и происходит нарушение доступа. Включи опцию и в ехе и в ДЛЛ Use dynamic RLT или работай с указателями на строку. Вообще правило такое: где создаешь ресурс там его и уничтожай. В СОМ для обхода такой стуации существует спец. интерфейс IMalloc, и еще много ухищрений, типа SysAllocString SysFreeString, SafeArrays и прочее.
Вообще есть хорошая штука, CodeGuard называется (в Билдере) Она в такие вещи сразу "носом тыкает" сообщением Resource from different RTL.

Build With Run-Time Packages тебе не поможет. Используй эту опцию для уменьшения размера кода. Но тогда ты должен поставлять все используемые проектом DLLки.


 
Digitman ©   (2004-08-05 10:15) [8]


> Юра   (05.08.04 09:49) [7]


> Build With Run-Time Packages тебе не поможет


еще как поможет
и уменьшение размера кода здесь ни при чем - это само собой разумеющееся


 
Юра   (2004-08-05 10:23) [9]

2Digitman
Не буду спорить. Давно на дельфях не программил. Во всяком случае, я постарался объяснить первопричину, а разобраться в опциях проекта, думаю, можно самому.


 
Digitman ©   (2004-08-05 10:37) [10]


> Юра   (05.08.04 10:23) [9]


тогда просто тебе для сведения : в случае сборки обоих проектов с ран-тайм пакетами эти проекты так же используют единый менеджер памяти


 
Slavka J. Borland   (2004-08-05 12:22) [11]

Есть такая замечателдьная везчь. Называется ShareMem.pas. Его пишешь ПЕРВЫМ модулем в библиотеки и программе. Не в PAS юните, а в DPR. Т.е. у тебя DPR примерно так выгдядит:

program ASMaker;

uses
 ShareMem, // - ОБЯЗАТЕЛЬНО ПЕРВЫМ СТАВЬ!
 Forms,
 SplashUnit in "SplashUnit.pas" {SplashForm},
 WizardUnit in "WizardUnit.pas" {WizardForm},
 ComponentUnit in "ComponentUnit.pas" {CompForm};

. . . . . .

Также в библиотеке. Тока тебе придется таскать с собой библиотеку brlndmm.dll (около 20 килов). Это юнит (ShareMem) станжартный. Т.е. есть уже в Delphi. Ставь, компилируй. Живи и радуйся. А вообще без него можно передавать строки типа ShortString, PChar, PAnsiString и т.д. Но вообще я сам SgareMem юзаю. Чего и вам желаю. В инете есть много юнитов, которые без DLL тебе могут заменить это все, но тут все же Borland делала, а они-то знают свое дело. Удачи в кодинге! :)


 
Slavka J. Borland   (2004-08-05 12:25) [12]

>> XShadow Dll не может возвращать String только PChar

Может! Еще как! Могу пояснить. Кому интересно: ICQ: 306684286


 
Думкин ©   (2004-08-05 12:35) [13]

> [11] Slavka J. Borland   (05.08.04 12:22)

Есть стороннее - без ДЛЛ.


 
GrayFace ©   (2004-08-05 14:23) [14]

А если возвратить PChar(IntToStr(i)), то все нормально будет?


 
Slavka J. Borland   (2004-08-06 06:07) [15]

>> Думкин ©   (05.08.04 12:35) [13]

Знаю, есть. У меня даже есть, даже могу дать. Сам модуль состоит из одного класса и его просто в uses надо прописать. Размер около 4 килобайт. Пишите, могу скинуть.

>> GrayFace ©   (05.08.04 14:23) [14]

Хм. . . .. не пробовал, но по идее все должно работать, т.к. ты передаешь указатель, а не саму строку. А вообще, еще раз говорю, мне легче не мучаться, а прикрепить к своему проекту файлик brlndmm.dll (BoRLaND Memory Manager)  размер в 30 килобайт и ShareMem в uses. Да потом, при желании, саму эту DLL можно пожать UPX"ом, а если хреново пожмется, то есть афигеный упаковщик, размер распаковщика которого сосбавляет 197 байт (!!!). F.S.G. назывется (F[ast] S[mall] G[ood]). Я им жму свои программы на MASM"е. Ента штукенция пожала прогу в 2,5 килобайта до 750 байт. Но я отвлекся от темы и потом все это на любителя. На вкус и цвет товарищей нет. Еще раз говорю, что я предпочитаю таскать с собой Борладновскую DLL и ShareMem в начале кажой программы.


 
-SeM-   (2004-08-06 12:04) [16]

Slavka J. Borland   (06.08.04 06:07) [15]

> то есть афигеный упаковщик, размер распаковщика которого
> сосбавляет 197 байт (!!!). F.S.G. назывется (F[ast] S[mall]
> G[ood])

Ссылочку можно?


 
GrayFace ©   (2004-08-07 10:03) [17]

Slavka J. Borland   (06.08.04 6:07) [15]
> не пробовал, но по идее все должно работать, т.к. ты
> передаешь указатель, а не саму строку.

Наверняка при возврате строки тоже передается указатель, иначе такой проблемы не было бы. Вот только при присвоении строк Delphi увеличивает счетчик ссылок - наверное, AV возникает из-за этого.


 
Мастер ©   (2004-08-07 20:15) [18]

>GrayFace ©   (07.08.04 10:03) [17]

И при работе со String(AnsiString) и с PChar возникает 2 варианта:

1. В вызываемой функции изменяется размер строки.
2. В вызываемой функции не изменяется размер строки.

В первом варианте необходимо использовать ShareMem, либо собирать программу с опцией Build with Runtime packages, так как для перераспределения памяти будут использоваться разные менеджеры памяти, что приведет к непредсказуемым, разрушительным последствиям.

Вот втором случае можно совершенно спокойно обрабатывать переданные строки.
Но нужно учитывать(в случае передачи String(AnsiString)), что передача параметров происходит через стек, и передать можно не более 255 байт.


 
sashok   (2004-08-07 21:51) [19]

Подключайте ShareMem в dll-ке и в программе и тогда можно использовать: string, strings.


 
Dizzy   (2004-08-11 10:52) [20]

Konsul!

Когда пишешь DLL общее правило такое: нормально передаются и получаются без дополнительных ухищрений только типы известные системе. Поскольку Windows знать не знают ни про какой String, пользуйся PChar. Почитай Марко Канту (www.marcocantu.com), очень просто и грамотно описывает что такое хорошо и что такое плохо при программировании на Delphi.


 
Мастер ©   (2004-08-11 11:33) [21]

>Dizzy   (11.08.04 10:52) [20]
Поскольку Windows знать не знают ни про какой String, пользуйся PChar

Ошибочка.
Читай комментарии к Wizard DLL.



Страницы: 1 вся ветка

Текущий архив: 2004.08.29;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.028 c
1-1091895346
Sourse
2004-08-07 20:15
2004.08.29
Как открыть файл с помощью моей программы


14-1089711465
TARIK
2004-07-13 13:37
2004.08.29
Робочие группы


14-1092240235
TUser
2004-08-11 20:03
2004.08.29
Вася Добрый уже ожил?


1-1092317081
Nata
2004-08-12 17:24
2004.08.29
CopyFiles


1-1092231625
andrey__
2004-08-11 17:40
2004.08.29
Организация очереди