Форум: "Основная";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
ВнизИспользование PChar в dll Найти похожие ветки
← →
Lammo (2004-05-16 19:15) [0]как правильно?
function Test(c: PChar): PChar;
var
s: String;
begin
s := StrPas(c); // либо просто s := c ?
s := s+"!";
Result := PChar(s);
end;
procedure TForm.ButtonClick(Sender: TObject);
var
str : String;
begin
str := "123";
ShowMessage(Test(PChar(str)));
end;
такой код правильный?
← →
MaxDDinc (2004-05-16 19:20) [1]Процедура ShowMessage работает с типом STRING, а Ваша функция возвращает PChar ... а преобразовать в STRING можно через String(pMyChar: pChar)
← →
Rouse_ © (2004-05-16 19:20) [2]Используй ShortString, огребешь меньше проблем...
← →
Lammo (2004-05-16 19:26) [3]
> Rouse_ © (16.05.04 19:20) [2]
А если его длинны недостаточно?
← →
Polevi © (2004-05-16 19:28) [4]COM сервер и WideString
← →
Lammo (2004-05-16 19:33) [5]
> Polevi © (16.05.04 19:28) [4]
Это уже слишком далеко.....
я просто спросил код правильный?
← →
Polevi © (2004-05-16 19:39) [6]мне не нравится
← →
Lammo (2004-05-16 19:43) [7]а как тогда?
← →
Гаврила © (2004-05-16 19:44) [8]WideString(COM не обязательно)
> такой код правильный?
не правильный в корне
вылетишь с ошибкой "неверный указатель", причем не сразу, а через некоторое время, искать ошибку замучаешься
← →
Lammo (2004-05-16 19:54) [9]function Test(c: PChar): PChar;
var
s: String;
h: PChar;
begin
s := StrPas(c);
s := s+"!";
h := PChar(s);
Result := @h^;
end;
так тоже нельзя?
← →
Гаврила © (2004-05-16 20:16) [10]так тоже нельзя
локальная переменная s освобождается при выходе за область видимости, то есть при выходе из функции test.
ТОчнее освобождается память, на которую переменная указывает.
Таким образом, результатом функции будет указатель на уже освобожденную память
← →
Lammo (2004-05-16 20:22) [11]тогда как сделать что б было все ок?
← →
Гаврила © (2004-05-16 20:44) [12]А что ты хочешь сделать ?
если функция сделана только
для добавления "!" к строке, используй widestring как результат и как параметр.
Неоптимально с точки зрения управленя ресурсами и быстродействием, зато оптимально с точки зрения скорости программирования
← →
Lammo (2004-05-16 21:02) [13]Я пишу dll, и в качестве параметров мне нужно передавать строки…
Я просто хочу знать как правильно использовать PChar в таких случаях. Можно пример пожалуйста?
← →
Гаврила © (2004-05-16 21:10) [14]
> Lammo (16.05.04 21:02) [13]
при работе с PChar важно помнить, кто выделяет память, а кто ее освобождает. Если при этом еще и ведется работа с разными модулями (dll и Exe - это модули), то ситуация несколько усложняется тем, что работают разные менеджеры памяти, для каждого модуля свой.
Общее правило - кто выделил память, то ее и освобождает.
Следовательно, выделять память в данном случае возможно должен exe, и передавать параметром процедуры в dll указатель на уже выделенный кусок памяти. Так работает большинство (если не все) функций API
← →
Lammo (2004-05-16 22:32) [15]Можно пример пожалуйста, уже целый день сижу все никак не могу разобраться.
← →
Rouse_ © (2004-05-16 23:19) [16]Может быть приведешь задачу более полно, так как именно в данном варианте я бы отказался от PChar и использовал несколько другой механизм...
← →
jack128 © (2004-05-16 23:45) [17]классический вариант, как это делаю я :-)
function Test(InputStr, OutputStr: PChar; MaxLength: Cardinal): LongInt;
var
s: String;
begin
s := InputStr;
s := s+"!";
...
if (Length(s) + 1) > MaxLength then
Result := 0
else
begin
Move(PChar(s)^, OutputStr^, Length(s));
OutputStr[Length(s) + 1] := #0;
end;
end;
procedure TForm.ButtonClick(Sender: TObject);
var
str : String;
str2: string;
begin
SetLength(str2, 1000);
str := "123";
SetLength(str2, Test(PChar(str), str2, Length(str2)));
ShowMessage(str2);
end;
← →
Polevi © (2004-05-17 10:39) [18]type
TTest = class(TAutoObject, ITest)
protected
function Test(const Str: WideString): WideString; safecall;
{ Protected declarations }
end;
implementation
uses ComServ;
function TTest.Test(const Str: WideString): WideString;
begin
Result:=Str+"!";
end;
procedure TForm.ButtonClick(Sender: TObject);
var
z:OleVariant;
begin
z:=CreateOleObject("Srv.Test");
ShowMessage(z.Test("123"));
wMessage(str2);
end;
← →
Lammo (2004-05-17 18:12) [19]Спасибо.
ок, а внутри dll, можно использовать тип String?
и еще, в качестве параметров string с фиксированной длинной (string[20])?
> jack128 © (16.05.04 23:45) [17]
код работать не будет...
← →
Lammo (2004-05-17 18:39) [20]
> Rouse_ © (16.05.04 23:19) [16]
Мне не нужны никакие «левые» способы реализации задачи…
Есть главный модуль и dll, внутри их все функции работают с типом String, я хочу знать каким образом можно передавать строки в качестве параметров, между главным модулем и dll, используя PChar.
Уже весь хелп перечитал, что-то все никак не доходит до меня…
← →
panov © (2004-05-17 18:48) [21]>Lammo
Самый простой способ решить проблемы в случае, если планируется использование DLL только при разработке в Delphi - использовать один менеджер памяти в Applicatino и в DLL:
uses ShareMem,... и в DLL и в файле проекта.
← →
Lammo (2004-05-17 19:22) [22]
> panov © (17.05.04 18:48) [21]
Я не думаю, что я буду использовать библиотеки написанные на других языках, но само условие, что их нельзя будет использовать в таком случае, меня не устраивает…
не отходите пожалуйста от темы, я ХОЧУ ИСПОЛЬЗОВАТЬ PCHAR! Зачем искать другие пути, я хочу научится.
Можете дать реально работающий пример, или ссылку где все нормально написано?
← →
Lammo (2004-05-17 19:23) [23]
> Lammo (17.05.04 18:12) [19]
← →
jack128 © (2004-05-17 20:55) [24]
> код работать не будет...
проясни?
← →
Fredericco © (2004-05-17 20:59) [25]function GetCoolPChar(StringIn: Pchar): Pchar ;
var
lpGlobalMemory: pointer ;
begin
lpGlobalMemory:=nil;
hGlobalMemory := GlobalReAlloc(hGlobalMemory,strlen(StringIn)+1, GMEM_MOVEABLE);
if hGlobalMemory <> 0 then { memory allocated OK }
begin
lpGlobalMemory := GlobalLock(hGlobalMemory);
lstrcpy(lpGlobalMemory,StringIn);
GlobalUnlock(hGlobalMemory);
end;
Result:= Pchar(lpGlobalMemory);
end;
В DLL:
function Test(c: PChar): PChar;
var
s: String;
begin
s := StrPas(c); // либо просто s := c ?
s := s+"!";
Result := GetCoolPChar(PChar(s));
end;
Не забудь в Initialization DLL сделать вот это:
hGlobalMemory := GlobalAlloc(GMEM_MOVEABLE , 1);
← →
Lammo (2004-05-17 21:17) [26]
> Fredericco © (17.05.04 20:59) [25
Спасибо.
А вроде ж можно как-то попроще, или нет?
← →
Fredericco © (2004-05-17 21:31) [27]Это самое простое, хоть и не правильное.
А что б правильно было см. Гаврила © (16.05.04 21:10) [14]
← →
Lammo (2004-05-17 21:35) [28]Блин, неужели все так тяжело?
Мастера, дайте пожалуйста правильный работающий код и, если можно, ссылку где про это все написано.
Заранее благодарен!
← →
Fredericco © (2004-05-17 22:16) [29]Вот ты неугомонный :-)
Есть ЕХЕ (Е) и ДЛЛ (Д). Ты из Е вызываешь функцию из Д. Хочешь получить обратно в Е результат. PChar это ссылка на область памяти. Кто эту память должен выделить? Микрософт считает что Е см. [14]. А ты как думаешь? В [25] пример, когда память выделается в Д, но это не правильно. Хорошо, простой способ. Ты его сам в своем первом посте привел. Там тоже, ессно, идет выделение памяти. Под переменную s:string. Эту память выделит и потом !обязательно! освободит Дельфи. Память помечается как свободная, то есть область памяти выделенная под результат твоей функции может быть еще не потерта, а может быть и потерта. Вероятность последнего, по моему опыту, ~40%. Как тут проще?
ЗЫ. Разве это сложно?
← →
evvcom © (2004-05-18 00:22) [30]
> Блин, неужели все так тяжело?
Если подумать, то здесь все просто. Обрати еще раз внимание на
> Кто эту память должен выделить? Микрософт считает что Е
> см. [14].
Посмотри, как функции API сделаны. Например,
function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer; stdcall;
В своем exe выделяешь память, не используя менеджер памяти Дельфи, например, lpString := HeapAlloc(..., ..., nMaxCount); И спокойно потом вызываешь GetWindowText с параметром PChar. И работать будет потом с чем угодно. Да, память освобождать тоже надо будет потом в exe: HeapFree(..., ..., lpString);
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.038 c