Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.049 c
1-1092396169
antonn
2004-08-13 15:22
2004.08.29
Опять рабочий стол...


14-1092133062
Kerk
2004-08-10 14:17
2004.08.29
В Финляндии не берут в армию из Интернета


3-1091864650
serg128
2004-08-07 11:44
2004.08.29
Как сортировать по вычислимому полю?


3-1091693682
Sirruf
2004-08-05 12:14
2004.08.29
BLOB-поля по-простому


4-1090241608
Григорьев Антон
2004-07-19 16:53
2004.08.29
Изменение порядка сообщений в очереди





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский