【发布时间】:2011-07-12 12:12:45
【问题描述】:
这个问题与我之前问过的this 问题有关。 @RRUZ 提供的代码正在运行,但似乎不太正确或 我做错了什么。
在执行GetSharedFiles 之后,TMyObject 的实例中发生了奇怪的事情。 FMyEvent 字段(应该是)nil 指向一些随机数据。
我在 5 分钟前发现的是,如果我关闭编译器选项中的优化,它在重建后可以正常工作。所以也许这是一些编译器错误?
这是代码快照(Delphi 2009 Windows 7 64 位):
unit Unit17;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm17 = class(TForm)
btnetst: TButton;
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyEvent = procedure(Sender: TObject) of object;
type
TMyObject = class(TObject)
private
FMyEvent: TMyEvent;
function GetSharedFiles: TStringList;
public
property OnEvent: TMyEvent read FMyEvent write FMyEvent;
procedure DoSomething;
end;
var
Form17: TForm17;
implementation
uses
ActiveDs_TLB,
ActiveX;
function ADsGetObject(lpszPathName:WideString; const riid:TGUID; out ppObject):HRESULT; safecall; external 'activeds.dll';
{$R *.dfm}
procedure TForm17.btnTestClick(Sender: TObject);
var
MyObject: TMyObject;
begin
MyObject := TMyObject.Create;
try
MyObject.DoSomething;
finally
if Assigned(MyObject) then
MyObject.Free;
end;
end;
{ TMyObject }
procedure TMyObject.DoSomething;
var
TmpList: TStringList;
begin
try
TmpList := GetSharedFiles; //something is overwritting the memory in object and puts random data to FMyEvent?
if Assigned(FMyEvent) then
ShowMessage('WTF'); //this should not be called, and if you comment out GetSharedFiles it won't.
finally
if Assigned(TmpList) then
TmpList.Free;
end;
end;
function TMyObject.GetSharedFiles: TStringList;
var
FSO : IADsFileServiceOperations;
Resources : IADsCollection;
Resource : OleVariant;
pceltFetched : Cardinal;
oEnum : IEnumvariant;
begin
Result := TStringList.Create;
//establish the connection to ADSI
if ADsGetObject('WinNT://./lanmanserver', IADsFileServiceOperations, FSO) = S_OK then
begin
//get the resources interface
Resources := FSO.Resources;
//get the enumerator
oEnum:= IUnknown(Resources._NewEnum) as IEnumVariant;
while oEnum.Next(1, Resource, pceltFetched) = 0 do
begin
Result.Add(LowerCase(Format('%s%s%s',[Resource.Path,#9,Resource.User])));
Resource:=Unassigned;
end;
end;
end;
end.
有什么想法吗? 感谢您的宝贵时间。
【问题讨论】:
-
我不认为这是一个编译器错误。很有可能您正在写入一些内存边界,并且 Delphi 在 Debug 模式下添加了额外的填充,因此防止您覆盖 FMyEvent。
-
好的,但我只使用这段代码,仅此而已。
-
您是否尝试过使用与 RRUZ 提供给您的 exact 相同的代码? (特别是摆脱 TStringList/LowerCase(Format(... in your code)?
-
如果我删除 Result.Add() 并只留下 LowerCase(Format('%s%s%s',[Resource.Path,#9,Resource.User])) 它可以工作。
-
"如果我删除 Result.Add() 并只留下..." - - - 可能您只是在更改触发 bug 显现的条件。
标签: delphi delphi-2009 access-violation