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

Вниз

Передача и получение строк из DLL   Найти похожие ветки 

 
dreamse   (2006-11-23 19:54) [0]

Приветсвую. Подскажите как нормально передавать строки в DLL и обратно

Подключение ShapeMem исключаеться так как неудобно

Через Pchar не получаеться, выдаёт какие то крякозябли :(
ShortString анологично - крякозабли ...

Подсказали передавать массив + размер массива а потом его востанавливать , но немогу разобраться как так как с массивами не работал нормально :(


 
Джо ©   (2006-11-23 19:56) [1]

> Через Pchar не получаеться, выдаёт какие то крякозябли :
> (
> ShortString анологично - крякозабли ...

Есть предложение — научиться передавать правильно, без кракозябликов.


 
dreamse   (2006-11-23 20:14) [2]

> Джо ©   (23.11.06 19:56) [1]

Возможно :)

В чём ошщибка ?

EXE :



Function ApiGetPath:pchar; external "my.dll";

procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage(ApiGetPath);
end;



DLL



function ApiGetPath: Pchar; stdcall;
begin
   result := Pchar("C:\1111\222\333");
end;



В ответ приходит либо крякозябли либо буква С :)


 
Джо ©   (2006-11-23 21:36) [3]

А посмотри, каковы способы передачи того-же PChar"а в функциях WinAPI. Суть в том, что PChar — это всего-лишь указатель на некую область памяти, в которой, предположительно, будет находиться нечто вроде "строки", т.е., печатаемые символы с завершающим символом с кодом 0.

Теперь смотри, что у тебя получается.
1. В функции ApiGetPath ты заводишь (неявно) константу-строку ("C:\1111...");
2. Приводишь ее к типу PChar.
3. Строки в Делфи — это объекты с управляемым временем жизни. Как только счетчик использования строки становится равным 0 (например, после выхода из функции, как у тебя), то этот объект разрушается.
4. Однако, адрес на эту область памяти ты возвращаешь в качестве результата функции. Повторяю, адрес, по которому строки уже нет.

Как поступать? Есть разные подходы, они отражены в WinAPI.
1. Выделяем память (динамически) под строку в самой функции. Возвращаем адрес на нее. Вызывающая программа, после того, как эта "строка" перестанет быть ей нужной, очищает память.

function ApiGetPath: Pchar; stdcall;
const
 S = "c:\123\456";
begin
 GetMem (Result, Length(S));
 StrCopy(Result,S)
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 P: PChar;
begin
 P := ApiGetPath;
 ShowMessage (P);
 FreeMem(P);
end;

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

2. Выделять память в основной программе и передавать указатель (PChar) на него в функцию, чтобы она записывала по этому адресу данные. Тонкость тут в чем? В том, что нужно заранее знать, сколько памяти выделить. Поступают обычно так: делают еще одну функцию, возвращающую размер, необходимый для хранения данных. В WinAPI это пара функций GetWindowTextLength/GetWindowText, используемых совместно. Второй подход: при передаче функции в кач-ве параметра nil она должна возвратить объем памяти, который ей необходим. После этого делается уже второй вызов, с указанием размера В WinAPI таких функций тоже немало.

function ApiGetPath2 (P: PChar): Integer;
const
 S = "c:\123\456";
begin
 if P = nil then
   Result := Length(S)
 else
 begin
   StrCopy (P,S);
   Result := 0;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 P: PChar;
 N: Integer;
begin

 N := ApiGetPath2(nil);
 GetMem (P, N);
 try
   ApiGetPath2(P);
   ShowMessage (P);
 finally
   FreeMem (P);
 end;
end;


Преимущества — память выделяется и освобождается в одном месте. Недостатки — некоторая громоздкость.

Остальные способы — комбинации и вариации этих основных.
В таком аксепте, в общем, почитай хорошие книги :)

---
Писал это все в спешке, поэтому неисключены опечатки, ляпы, описки и просто грубые ошибки ;)


 
dreamse   (2006-11-23 22:23) [4]

Спасибо конечно , буду разбираться. Но все кстати говорят что Pchar нормально передаёться ...

Когда передаю строку из DLL отлично принимаеться строка и всё ништяк.
Когде же передаю Строку в DLL то она приходит уже искажёная ... :(


EXE

procedure texts(value:pchar); external "Project1.dll";

procedure TForm1.Button1Click(Sender: TObject);
begin
texts(Pchar("123"));
end;

DLL

procedure texts(value:pchar); stdcall;
begin
Showmessage(StrPas(value));
end;

exports
texts;



Блин ... неужели нельзя просто передать строку блин в DLL ?


 
dreamse   (2006-11-23 22:32) [5]

Буду возиться с памятью :)


 
Desdechado ©   (2006-11-23 22:44) [6]

и помни - соглашения о вызовах должны быть одинаковы для функции. Если она у тебя в DLL описана как stdcall, то и в вызывающей программе тоже должна


 
Loginov Dmitry ©   (2006-11-23 23:25) [7]

> Подключение ShapeMem исключаеться так как неудобно


Это что еще за монстр?


 
dreamse   (2006-11-23 23:31) [8]

> Desdechado ©   (23.11.06 22:44) [6]

В этом то и была вся пробламма !! Спасибо !

Всем большое спасибо ! :)


 
Leonid Troyanovsky ©   (2006-11-25 12:14) [9]


> dreamse   (23.11.06 23:31) [8]
> > Desdechado ©   (23.11.06 22:44) [6]

> В этом то и была вся пробламма !! Спасибо !


Это вовсе не вся проблема.
Читать [3] до просветления.

--
Regards, LVT.



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

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

Наверх




Память: 0.47 MB
Время: 0.043 c
2-1164046288
~Aid~
2006-11-20 21:11
2006.12.10
TStringGrid


15-1164011476
Gavrila
2006-11-20 11:31
2006.12.10
TTreeView: как правильно использовать метод AddObject?


8-1145944179
TRyaSS
2006-04-25 09:49
2006.12.10
Как найти угол между отрезком и осью(любой )


15-1164010694
Ольга
2006-11-20 11:18
2006.12.10
как убрать ошибку "invalid variant type conversion"


15-1164103022
Mva
2006-11-21 12:57
2006.12.10
Не компилируется проект





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