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

Вниз

Передать из DLL большую строку   Найти похожие ветки 

 
MaxSit   (2002-04-04 20:45) [0]

Вопрос такой: как из DLL передать очень длинную строку? Использовать String и Sharemem к ниму не предлогать.
Заранее спасибо.


 
LazorenkoX   (2002-04-04 20:51) [1]

PChar


 
MaxSit   (2002-04-04 21:03) [2]

Да вот, не пашет. Говорит, Аксес виолатион у Вас, батенька.

procedure MyProc(var Per: PChar); StdCall; external DLL_Const Name "MyProcDLL";

q:=LoadLibrary(DLL_Const);
Per:=PChar("Привет");
MyProc(Per);
showmessage(Per); --> вот и вылетает;
FreeLibrary(q);

Что я делаю не так?


 
MaxSit   (2002-04-04 21:03) [3]

Да вот, не пашет. Говорит, Аксес виолатион у Вас, батенька.

procedure MyProc(var Per: PChar): Boolean; StdCall; external DLL_Const Name "MyProcDLL";

q:=LoadLibrary(DLL_Const);
Per:=PChar("Привет");
MyProc(Per);
showmessage(Per); --> вот и вылетает;
FreeLibrary(q);

Что я делаю не так?


 
LazorenkoX   (2002-04-04 21:23) [4]

Твой Unit:

//Сначала надо объявить процедуру
function MyProc(var Per: PChar): Boolean;

implantation

begin
//Загружаем библиотеку
q:=LoadLibrary(DLL_Const);
//ЗАДАЁМ АДРЕС ПРОЦЕДУРЫ!!! (точно не помню параметры):
@MyProc:=GetProcAddress(q, "MyProc");
//Теперь вызываем.
MyProc(Per);
showmessage(Per); --> вот и вылетает;
FreeLibrary(q);
end;

Если не получится попробуем изменить код ДЛЛки


 
Fantasist   (2002-04-04 22:43) [5]

Да нет, подключать можно и статически, тогда LoadLibrary делать не надо.
Покажи код MyProc.


 
MaxSit   (2002-04-04 23:13) [6]

Ошибка возникает, если вызываешь и статически и динамически, разницы нет.

Вот сама DLL:

procedure MProcDLL(Per: PChar); StdCall; exports MProcDLL;
...
procedure MProcDLL(Per: PChar);
begin
try
Application.Create(TForm1, Form1);
Form1.Memo1.Add(Per);
Form1.ShowModal;
Per:=PChar(Form1.Memo1.Text); // может тут загвостка, предполагаю.
finally
Form1.Hide;
Form1.Free;
end;
end;

Мне кажется, что PCHAR это указатель, который теряется после уничтожения формы. Поправьте, если не так.


 
Fantasist   (2002-04-05 00:01) [7]

>Ошибка возникает, если вызываешь и статически и динамически, разницы нет.

Mы в это и не сомневались. Тут лучше действительно потрейсить dll так как скорее всего твое предположение верно. PChar - это указатель на char, а преобразование:

p:pchar;
s:string;
p:=PChar(s);

скорее всего означает то же, что и
p:=@s[1];

Да должно быть так. Я просто точно не помню, может все-таки Delphi извратился, и создает копию, но это легко проверить.


 
MaxSit   (2002-04-05 00:22) [8]

Причем, если сделать:

try
// Application.Create(TForm1, Form1);
// Form1.Memo1.Add(Per);
// Form1.ShowModal;
Per:=PChar("Блин, ну когда уже заработает");
finally
// Form1.Hide;
// Form1.Free;
end;
end;

то все работает без проблем ??? Значит побороть то можно...


 
LazorenkoX   (2002-04-05 00:28) [9]

Это конечно глупое предположение, но давай сделаем как можно меньше сомнений.

Попробуй добавь это в главный бегин ДЛЛки:

begin
Application.Initialize;
Form1 := TForm1.Create(Application);
Application.Run;
end;


И убери из своего кода Application.Create(TForm1, Form1);


 
MaxSit   (2002-04-05 00:45) [10]

Идея интересная, даже все заработало, но стала выдаваться следующая ошибка, после завершения всего приложения:

"A call to an OS function failed."

Заработал другой вариант: объявил глобальную переменную в DLL, присваеваю значение Form1.Memo1.Text, затем грохаю форму, и только потом пишу:

Per:=PChar(Global_Var_PChar);

Все работает, спасибо за наводку.


 
MaxSit   (2002-04-05 00:48) [11]

Вероятно не очень понятно:

Вот сама DLL:

procedure MProcDLL(Per: PChar); StdCall; exports MProcDLL;

var Global_Var_PChar: String;
...
procedure MProcDLL(Per: PChar);
begin
try
Application.Create(TForm1, Form1);
Form1.Memo1.Add(Per);
Form1.ShowModal;
Global_Var_PChar:=Form1.Memo1.Text;
finally
Form1.Hide;
Form1.Free;
end;
Per:=PChar(Global_Var_PChar);
end;
и именно в таком порядке...


 
Sergey_n   (2002-04-05 01:15) [12]

Попробй поюзать SAFEARRAY, иногда помогает ;))))


 
Fantasist   (2002-04-05 02:43) [13]

Ну че вы извращаетесь то. :) Клуб мазохистов? :D

Почему работает это:
Per:=PChar("Блин, ну когда уже заработает");

Потому что, в отличие от:
Per:=PChar(Form1.Memo1.Text);

Здесь не только возвращается адрес(его пока еще не существует), но и выделяется память. То есть вначале она выделяется, а потом возвращается адрес на эту память.Функции WinApi в таких случаях требуют от вас выделить память, прежде чем передавать им PChar.
Можно так и делать в вашем случае. Память можно выделить StrAlloc. Это можно, конечно, сделать и в dll, но тогда клиент должен сам заботиться об освобождении памяти.

Так как у вас здесь:

var Global_Var_PChar: String;
...
procedure MProcDLL(Per: PChar);
begin
try
Application.Create(TForm1, Form1);
Form1.Memo1.Add(Per);
Form1.ShowModal;
Global_Var_PChar:=Form1.Memo1.Text;
finally
Form1.Hide;
Form1.Free;
end;
Per:=PChar(Global_Var_PChar);
end;


Выглядит очень удобно, так как компилятор за вас производит необходимое выделение и освобождение памяти(операции с переменно string) Однако, вот так вот:
Per:=PChar(Global_Var_PChar);
Вы передаете адрес на ваш Glodal string и клиент использует этот адрес. Теперь если вы внезапно поменяете значение Global_Var_PChar в своей dll, то клиент с удивлением обнаружит, что его строка которую он получил из вашей dll изменилась сама собой без всяких действий с его стороны!



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

Форум: "Основная";
Текущий архив: 2002.04.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.009 c
1-57804
ZPS
2002-04-06 00:38
2002.04.18
PopupMenu1 - поменять цвет ?


1-57793
новенький в Делфи
2002-04-06 00:25
2002.04.18
как прогу к часикам затолкать?


1-57817
DenKop
2002-04-05 22:54
2002.04.18
Форма поверх всех окон.


1-57748
PVOzerski
2002-04-05 13:30
2002.04.18
Dynamic-методы в объектах старого стиля - что это такое изнутри?


7-57901
ATLANTIDO
2002-01-25 13:35
2002.04.18
кЛАВА





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский