Форум: "Основная";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];
Внизпередача PChar в DLL Найти похожие ветки
← →
RWolf © (2007-03-11 10:38) [0]Сижу сейчас за кодом и откровенно не соображаю, в чем дело. Программа вызывает экспортированную функцию в DLL, вот так:
TServerState=procedure(address,code,title:PChar;const info,players:array of PChar);stdcall;
...
plugin.ServerState(PChar(address),PChar(game.Code),PChar(game.Title),pcinfo,pcpl ayers);
В DLL функция делает следующее:
procedure ServerState(address,code,title:PChar;const info,players:array of PChar);stdcall;
var s1,s2,s3:String;
...
try
s1:=address;
s2:=code; // <---
s3:=title;
...
except
on e:Exception do flog(e.Message);
end;
в строчке, отмеченной комментарием, судя по логу, иногда возникает Access violation ... Write of address 10018027.
Собственно, хотелось бы узнать причину, поэтому вопрос такой: корректна ли такая передача параметров в DLL? может, я чего важного не знаю насчет дельфовского менеджера памяти?
← →
clickmaker © (2007-03-11 12:09) [1]а точно в этой строке?
в приведенной части кода все законно
на всякий случай, как game.Code инициализируется? и не может ли он стать невалидным к моменту s2:=code?
← →
RWolf © (2007-03-11 12:39) [2][b]clickmaker[/b], game - глобальная переменная, заполняется единожды при старте, объявлена так:
[code]type
TDefs=record
Code:string;
Title:string;
...
end;
var
game:TDefs;[/code]
← →
MBo © (2007-03-11 12:41) [3]>array of PChar
динамический массив передаешь - а о ShareMem позаботился?
← →
RWolf © (2007-03-11 13:02) [4][b]MBo[/b], верно - про string помню, а про д.м. - забыл. Буду переделывать.
← →
Belorus © (2007-03-11 15:47) [5]FASTMM4 используй.
← →
Аноним (2007-03-11 16:17) [6]Не надо фаст ММ
и ShareMem не надо
Надо использовать типы, которые не вынуждают использовать внешние менеджеры
← →
RWolf © (2007-03-11 19:11) [7]Переписал, и что бы вы думали? глюк не исчез :)
Теперь вызов выглядит так:
TServerState=procedure(address:PChar; game:PGameDefs;
nInfo:Integer; info:PChar;
nPlayers:Integer;names:PChar;frags:PInteger
);stdcall;
TGameDefs=record
Code: PChar;
...
end;
PGameDefs=^TGameDefs;
var
game:PGameDefs; //заполняется при старте
...
plugin.ServerState(
PChar(address),game,
Length(info),PChar(plug_info),
players.Count,PChar(plug_players),PInteger(plug_frags));
Плагин:
procedure ServerState(address:PChar; game:PGameDefs;
nInfo:Integer; info:PChar;
nPlayers:Integer;names:PChar;frags:PInteger);stdcall;
...
s1:=address;
s2:=game.Code; //здесь AV через произвольное число вызовов
Было замечено следующее. Далее плагин передает строчку s2 функции, которая вызывает TDataset.Locate:
procedure GameLocate(const gametype:string);
begin
Form1.fdGames.Locate("GAMETYPE",string(gametype),[loCaseInsensitive]);
...
end;
Приведение к string оставалось с того времени, когда параметр имел тип PChar; по идее, от приведения string->string логика меняться не должна. Тем не менее, если убрать приведение, глюк исчезает. Баг в менеджере памяти, или неучтенные особенности поведения типов String или Variant?
← →
trubin © (2007-03-11 21:11) [8]
> var
> game:PGameDefs; //заполняется при старте
А как заполняется?
Если примерно так:
procedure StartProc;
var
s: string;
begin
s:= "qwerty";
game.Code:= PChar(s);
end;
то понятно: т.к. string тип с управляемым временем жизни, и к моменту вызова ф-ии из ДЛЛ-ки по адресу game.Code может быть AV. Уж как повезет.
Для game.Code надо выделять память, и потом не забыть ее освободить.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.05.06;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.05 c