CLI/C++ DLL 包装非托管 DLL,在 .NET 中运行时崩溃(ieshims.dll 和 gpsvc.dll 丢失)
我继承了一个未修改的 DLL(最初由 C 代码构建)并希望在 .NET 项目中使用它。我有将 DLL 的功能包装在 C++ 类型对象中的头文件,我想要公开的正是这种面向对象的功能。当我在标准 C++ (Win32) 项目和 C++/CLI 项目中 #include 这些头文件并引用原始 DLL 时,一切正常。
使用 Visual C++ Express 2010,我尝试为 .NET 构建托管 DLL。然后,由于依赖性问题,该 DLL 在运行时崩溃。依赖步行者 说:
警告:至少未找到一个延迟加载依赖模块。
警告:由于延迟加载相关模块中缺少导出函数,至少有一个模块存在未解析的导入。
并抱怨找不到 gpsvc.dll 或 ieshims.dll。我知道这与 x86 与 x64 有关(我在 x64 上运行 Win7),但是,由于我可以在 C++ 项目中使用系统上的 DLL,我怀疑必须可以将其包装在托管 DLL 中以供使用在同一系统上的.NET 中。
预先非常感谢任何能够提供任何见解的人!
(顺便说一句,我的目标是开发一个 .NET 程序集,而不是直接在原始 DLL 上使用 p/invoke,因为在我之后许多互操作经验有限的 C#/VB 程序员将使用它)
I have inherited an unamanged DLL (originally built from C code) and want to use it in a .NET project. I have header files which wrap the DLL's functionality in a C++ type object, it is this object-oriented functionality I want to expose. Everything works fine when I #include these header files it in a standard C++ (Win32) project and in a C++/CLI project, referencing the original DLL.
Using Visual C++ Express 2010, I have tried to build a managed DLL for .NET. This DLL then crashed at runtime because of dependency issues. Dependency walker says:
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
and complains that it can't find gpsvc.dll or ieshims.dll. I know this has something to do with x86 vs x64 (I am running Win7 on x64) but, since I can use the DLL on my system in a C++ project, I suspect it must be possible to wrap this in a managed DLL for use in .NET on the same system.
Thanks very much in advance to anyone who can offer any insight!
(by the way, my goal is to develop a .NET assembly instead of using p/invoke directly on the original DLL, since it will be used by a lot of C#/VB programmers with limited interop experience after me)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案:x86/x64 问题是一个转移注意力的问题。我有一个由三个 dll 组成的长依赖链。 Visual Studio 的所有引用的“复制本地”属性都设置为 true,因此我引用的托管 dll 被复制到本地,远离其依赖项。
由于某种原因,我无法弄清楚,将引用的复制本地属性设置为 false 并删除它所做的本地副本并不能解决问题。我必须将依赖项复制到 C# 项目的本地 bin。
一个潜在的收获是,过多关注依赖遍历器中缺少的调用时间依赖关系可能会导致您走向错误的方向。
Solution: the x86/x64 issue is a red herring. I had a three-dll long chain of dependencies. Visual Studio's 'copy local' property for all references was set to true, so the managed dll I was referencing was copied local, away from its dependencies.
For some reason I can't figure out, setting the copy local property of the reference to false and deleting the local copy it made does not solve the problem. I had to copy over the dependencies to the C# project's local bin.
A potential takeaway is that paying too much attention to absent call-time dependencies in dependency walker may lead you in the wrong direction..
正如您 Rory 在您的回答中提到的那样,解决方案似乎是您需要在 C# 应用程序的引用部分中包含所有依赖的 DLL/手动包含 C# bin 或 .exe 正在运行的同一文件夹中的所有 DLL从。
我刚刚遇到了这个问题,设置与你的类似。我有以下依赖项:
C# application -> (1) CLI 包装DLL -> (2) C++包装DLL-> (3) 3rd Party DLL
在参考部分中,我包含了 (1) CLI DLL。我没有包含 (2) C++ DLL,因为它抛出错误
ERROR ...无法添加。请确保该文件可访问,并且它是有效的程序集或 COM 组件
(解释:C++ DLL 不兼容 .NET/CLR)。然后我简单地假设,由于 (1) CLI DLL 正确且成功地链接到 (2) C++ DLL(我使用 C++/CLI 控制台应用程序对此进行了测试),C# 应用程序将能够通过引用的 (1) CLI 依赖项访问 (2) C++ 依赖项。这是不正确的。
我不知道原因,但 C# 应用程序无法访问 CLI 的依赖项。
我的解决方案是手动将 (2) C++ DLL 包含在 .exe 目录中。请记住,如果
本地复制
设置为 true,则会自动复制 (1) CLI DLL在 C# 应用程序中。我似乎没有遇到任何问题(2)C++ DLL 引用(3)第 3 方 DLL(即(3)第 3 方 DLL 可以驻留在其指定的路径中/不需要在本地复制)。As you, Rory, mentioned in your answer, the solution seems to be that you need to include ALL dependent DLLs in the References section of your C# application/manually include all DLLs in the C# bin or the same folder that the .exe is running from.
I just ran into this issue with a similar setup to yours. I have the following dependencies:
C# application -> (1) CLI Wrapper DLL -> (2) C++ Wrapper DLL -> (3) 3rd Party DLL
In the References section, I included the (1) CLI DLL. I did not include the (2) C++ DLL because it throws the error
ERROR ...could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component
(interpretation : C++ DLL is not .NET/CLR compliant).I then simply assumed that because the (1) CLI DLL correctly and successfully linked to the (2) C++ DLL (I tested this with a C++/CLI Console Application), the C# application would be able to access the (2) C++ dependency through the referenced (1) CLI dependency. This was incorrect.
I don't know the reason why, but the C# application cannot access the CLI's dependencies.
My solution was manually include the (2) C++ DLL in the .exe's directory. Remember that the (1) CLI DLL is automatically copied over if
Local Copy
is set to true in the C# application. I did not seem to run into any issues with the (2) C++ DLL referencing the (3) 3rd Party DLL (i.e. (3) 3rd Party DLL could reside in its specified path/did not need to be locally copied).