SafeArray? SafeArray? 有人知道对SafeArray的访问的控制吗? (200分)

  • 主题发起人 主题发起人 LLLYJ
  • 开始时间 开始时间
L

LLLYJ

Unregistered / Unconfirmed
GUEST, unregistred user!
本人在开发一个软件,通过在COM对象中使用SafeArray来保存数据,
例子:
IDXData = interface(IDispatch)
function Get_Data : PSafeArray; stdcall;
...
property Data : PSafeArray read Get_Data;
end;

我另有一个线程,希望使用它实现对于数据的异步处理,
TDXSendDaemon = class(TThread)
private
FInEventHandle : THandle;
FOutEventHandle : THandle;
FDxDataLock : TCriticalSection;
FObjStream : Pointer;
protected
procedure ExecuteSend; virtual;
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
procedure SendMessage(const ADXData: IDXData);
end;

procedure TDXSendDaemon.Execute;
begin
CoInitialize(nil);
try
while not Terminated do
begin
if WaitForSingleObject(FInEventHandle,50) = WAIT_OBJECT_0 then
begin
try
ExecuteSend;
except
on e : exception do
begin
//Terminate;
DebugMessageFmt('%s,%s',[e.classname, e.message]);
raise;
end;
end;
end;
end;
finally
CoUnInitialize;
end;
end;

procedure TDXSendDaemon.ExecuteSend;
var
Rslt : HRESULT;
Intf : IDXData;
PSa : PsafeArray;
DataPtr : Pointer;
begin
Rslt := CoGetInterfaceAndReleaseStream(IStream(FObjStream), IDXData, Intf);
FObjStream := nil;
SetEvent(FOutEventHandle);
OLECheck(Rslt);

if Assigned(Intf) then
begin
PSa :=Intf.Data;
Rslt := SafeArrayAccessData(PSA, DataPtr);
OleCheck(Rslt);
try
//; do my process on DataPtr
finally
SafeArrayUnAccessdata(PSA); // 基本上到这儿就会出错,且CPU占用达到100%
end;

Intf := nil;
end;
end;

有谁碰到过这样的问题吗?[gold]重金酬谢![/gold]
 
高手们加油啊,我等着回答呢,分数可以商量。

[red]急!!!急!!![/red][:(]
 
如果不试验一下,真的看不出什么问题
SafeArrayAccessData 是为了提高访问速度,把内存锁住,
建议你先去掉这个功能试验一下
 
但好象对于SafeArray的访问都需要Lock/Unlock的。

谢谢你,终于有人回答。

---------------------------
众多高手赶紧现身啊,小弟不知怎么办了!!!
 
我有此问题,高手伸伸举手之劳。
 
思考中、、、
 
我觉得你要先用SafeArrayCreate()创建一个数组边界!
 
toYB_unique: 我觉得你要先用SafeArrayCreate()创建一个数组边界!

已经在创建期间调用了SafeArrayCreate,并且确定了数组的边界。
 
我觉得出错的原因是引用的 Stream 最后没有 nil 或者是 Rslt 最后没有释放引起的!
 
如果是SafeArrayUnAccessdata()引起的,建议你看看下面的文档!
http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarextvb/html/msdn_article5.asp
 
看来此问题的解决还很成问题。

难道这问题真的有这么难?
 
200 分也没有人要?
 
其实这反映了这样一个事实:我们的开发人员基本上不注重基于COM结构的开发,
不太注意系统的组织问题。

应该反省啊(我也一样!)
 
SafeArrayAccessData (psa, ppvdata)是锁住变体数组得到指向数组数据体的指针,此时的
ppvdata等同于正常的数组,可以简化变体转换过程,提高数据操作速度。另外,在MS SDK
中有一个附加说明,ppvdata所指向的数组必须大于64k。
  其实实现同样的功能DELPHI提供了两个相似的方法:VarArrayLock(const A: Variant): Pointer;
和 VarArrayUnlock(var A: Variant);
所以你也可以写成:
  DataPtr:=VarArrayLock(PSA);
.....
VarArrayUnlock(PSA);
 
后退
顶部