Ian*_*oyd 35 .net delphi com ccw com-callable-wrapper
我使用以下命令创建一个COM对象(来自本机代码)CoCreateInstance
:
const
CLASS_GP2010: TGUID = "{DC55D96D-2D44-4697-9165-25D790DD8593}";
hr = CoCreateInstance(CLASS_GP2010, nil, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, IUnknown, out unk);
Run Code Online (Sandbox Code Playgroud)
实际上,我在Delphi中,这意味着我调用了辅助函数:
CreateComObject(CLASS_GP2010);
Run Code Online (Sandbox Code Playgroud)
大部分时间这个功能都成功了.但有时,在同一个可执行文件中,在同一进程中,调用CoCreateInstance
失败的原因是:
Unspecified error (0x80004005 = E_FAIL)
Run Code Online (Sandbox Code Playgroud)
再次调用该函数可能会成功,或者可能会失败.没有(明显的)押韵或理由.
如果这是一个正常的 COM DLL,我写,我就开始把OutputDebugString
在DLL_ATTACH
,当有人试图打电话DllGetClassObject
,我会确认COM是正确加载我的DLL,并且它被正确要求被实例化的类.
不幸的是,它不是COM dll; 它是一个.NET程序集dll.COM子系统并不是简单地 "加载"我的dll
.相反,COM被指示加载mscoree.dll
:
HKEY_CLASSES_ROOT
CLSID
{DC55D96D-2D44-4697-9165-25D790DD8593}
InprocServer32
@default = mscoree.dll
Run Code Online (Sandbox Code Playgroud)
并mscoree.dll
导出所需的GetClassObject
功能.那mscoree.dll
个人回来了E_FAIL
,不是我.故障永远不会发生在我的开发机器上,但始终在客户机器上间歇性地失败.
问题是,因为mscoree.dll
返回的是E_FAIL
(而不是任何有用的):我如何告诉我问题是什么?
例如,似乎唯一遇到故障的客户(除了是唯一大量使用COM对象的客户)恰好在Windows XP上.也许他们遇到了.NET框架中的已知错误(版本4之前),您无法在同一进程中加载不同版本的.NET运行时:
这样做会引入CLR版本依赖项,这可能与主机进程预期的CLR版本冲突
使用COM包装器时,MSDN上的一篇文章中也提到了这种失败模式.您可以选择指定clrVersion
:
如果已加载另一版本的CLR并且可以在进程中并行加载指定的版本,则会加载指定的版本; 否则,使用加载的CLR.这可能会导致负载故障.
如果这是我在Windows XP上的间歇性加载失败的原因,或者是.NET框架上的早期版本,我怎么能mscoree.dll
告诉我这个?
如果原因是别的,我怎么让.NET告诉我?
至少,如果您要在 Visual Studio 的调试器中运行它,您可能能够捕获第一次机会的异常并获得一些见解。至少,您想知道哪种错误会导致 E_FAIL。即使您没有调试符号,您也应该能够执行此操作。
此外,即使您无法在同一进程中加载多个 .NET VM,通过对 App.config 和 .dll 清单进行一些手动操作,您也可以在同一个 .NET VM 中加载 .dll,即使它们是针对不同的版本进行编译的。
最后,检查应用程序事件下的 Windows 事件查看器,看看是否有任何记录。
归档时间: |
|
查看次数: |
835 次 |
最近记录: |