在dll中动态创建XmlDoc并操作的接口函数中首尾对应写了ActiveX.Coinitialize与CoUninitialize,结果运行到DLL中的CoUninitialize有无法捕获的异常,如果dll中不加这两句代码而加在Exe中则没有问题.有朋友告诉我说把后面的CoUninitialize代码注释掉.
若在DLL中不调用CoUninitialize会有什么问题?delphi的帮助文档中说
Comments
Typically, CoInitialize is called only once in the process that uses the OLE library. There can be multiple calls, but subsequent calls return S_FALSE. To close the library gracefully, each successful call to CoInitialize, including those that return S_FALSE, must be balanced by a corresponding call to the CoUninitialize function.
最后一句说每个CoInitialize的调用都要有CoUninitialize来一一对应.请高手指点....THX
若在DLL中不调用CoUninitialize会有什么问题?delphi的帮助文档中说
Comments
Typically, CoInitialize is called only once in the process that uses the OLE library. There can be multiple calls, but subsequent calls return S_FALSE. To close the library gracefully, each successful call to CoInitialize, including those that return S_FALSE, must be balanced by a corresponding call to the CoUninitialize function.
最后一句说每个CoInitialize的调用都要有CoUninitialize来一一对应.请高手指点....THX
procedure DllEntry(Reason: Integer);
begin
case Reason of
DLL_PROCESS_ATTACH,
DLL_THREAD_ATTACH:CoInitialize; DLL_PROCESS_DETACH,
DLL_THREAD_DETACH:CoUninitialize;
end;
end;
用这样的方法CoUninitialize是不会异常,但为什么写成如下就会有无法捕获的异常了呢?
function AAA:WideString;stdcall;
begin
CoInitializa(nil);
......
......
CoUninitialize; //执行至此则异常
end;
首先感谢您的回复.但还有不明:
我在function AAA:WideString;stdcall;中动态创建了Component和XmlDocument对象(局部变量),并均在函数体内调free释放,且代码全包含在CoInitialize与CoUninitialize之间,不明白为什么这样也会有问题,而且还是无法捕获的异常.
var
ret:WideString;
begin
ret:=GetXmlStr; //声明于DLL中的接口
ShowMessage(ret);
end;Dll中接口代码function GetXmlStr:WideString;stdcall;
var
AComp:TComponent;
AXml:TXmlDocument;
begin
Activex.CoInitialize(nil);
try
AComp:=TComponent.Create(nil);
AXml:=TXmlDocument.Create(AComp);
try
AXml.Active:=True;
AXml.DocumentElement:=AXml.CreateNode('TestRoot');
AXml.DocumentElement.Attributes['DateTime']:=FormatDateTime('YYYYMMDDHHMMSSZZZ',Now);
Result:=AXml.XML.Text;
finally
AXml.Free;
AComp.Free;
end;
except on e:Exception do
Result:=e.Message;
end;
// try
activex.CoUninitialize;
// except on e:Exception do
// Result:=Result+'===='+e.Message;
// end;
end;
已经是很简单的了 所以一直想不明白.
后面增加一条
AXml := Nil;
看看是否有效。
把AXml.Free改为FreeAndNil(AXml)也无效
执行到CoUninitialize会报Access Violation
若将最后的try except取消注释 此处无法捕获取异常信息
initialization
CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
CoUninitialize;
要把你在 CoUninitialize 之前加 sleep() 和 peekmessage 试一试
比如在主线程中获得了COM对象的接口,并要把接口传入到工作线程中使用,那么需要对接口进行列集散集
用到API为 CoMarshalInterThreadInterfaceInStream 和 CoGetInterfaceAndReleaseStream 对于没有调用CoUninitialize,后面如要再调用CoInitialize时就会失败了。
程序不出错不代表没有问题。应当成对调用。