我继承了一个旧的MFC/Win32 32 C++应用程序,它是我不应该编辑的源代码。
此MFC应用程序需要承载一个旧的MFC/Win32 32 C++ DLL。此DLL还试图通过混合模式包装器对托管C++/CLI DLL进行函数调用。我知道这听起来有点让人困惑,下面是我的意思的图表:
Old MFC/Win32 Application (NO CLR)
---> Hosting old MFC/Win32 DLL (NO CLR)
---> Making function calls to Mixed-Mode wrapper (CLR)
---> Sending function calls to C++/CLI DLL (CLR)我目前的问题是,当我试图挂载C++/CLR包装类的对象时,假设是WrapperClass WC;,MFC/ when 32应用程序会遇到“未处理的异常”。
我有一种感觉,我可能需要以某种方式将CLR托管在一个单独的进程中,以便能够生成对象。这主意对吗?还是我完全疯了?
代码编译时,这只发生在运行时。
有什么想法吗?
下面是我试图运行的代码的一个示例:
MFC/Win32 32 DLL
#include "WrapperClass.h"
BOOL Test::bTest() //This function is called elsewhere within MFC/Win32 DLL
{
DWORD dwTest;
WrapperClass WC; //Unhandled exception here!
return WC.FunctionToCall(dwTest); //FunctionToCall is a BOOL
}混合模式包装器类
BOOL WrapperClass::FunctionToCall(DWORD dw)
{
GCHandle h = GCHandle::FromIntPtr(IntPtr(m_impl)); //m_impl def'd as void *
CPPCLIClass^ CCC = safe_cast<CPPCLIClass^>(h.Target);
return (BOOL)CCC->FunctionToCall(dw);
}C++/CLI DLL
bool CPPCLIClass::FunctionToCall(UInt32 ui32)
{
if (ui32 == 42)
{
return true;
}
}更新:--我已经设法把一个真正的异常从程序中引出来了。我现在收到了一个System.IO.FileNotFound异常,并提供了其他信息,声明:
An unhandled exception of type 'System.IO.FileNotFoundException' occured in
Unknown Module.
Additional information: Could not load file or assembly 'CPPCLIProject,
Version=1.0.4351.29839, Culture=neutral, PublicKeyToken=null' or one of its
dependencies. The system cannot find the file specified.这意味着什么吗?我知道它显然找不到CPPCLIProject (注:这不是包装器项目),但是如果我从混合模式包装器在.lib文件上链接,那么我怎么会不接收链接器错误呢?
发布于 2011-11-30 20:20:54
您确定WrapperClass::FunctionToCall()的实现没有引发异常吗?看起来,您正在缓存CLR对象的内存位置,然后尝试调用其成员之一。我认为CLR可以自由地移动对象,所以您可能正在尝试使用已经移动的对象。
如果您将WrapperClass::FunctionToCall()的实现更改为一些简单的东西(例如创建一个CLR对象,调用一个成员函数),那么仍然会得到相同的未处理异常吗?
UPDATE:哪个类在CPPCLIProject - CPPCLIClass中?假设该项目表示C++/CLI,听起来它只是在需要调用类时找不到加载它的程序集。
相对于应用程序的其余部分,磁盘上的程序集在哪里?如果您的根EXE是非托管的(听起来是这样的,因为它是MFC/don 32),那么CLR将在EXE的目录和GAC中查找以加载程序集(我不认为它在路径中,但我对此不肯定)。
因此,如果CPPCLIProject不在与EXE位于同一个目录中,这可能是您的问题。
发布于 2011-11-30 19:42:15
你最好的选择是
try/catch.)
其想法是将“未知异常”转换为“已知异常”。
通常情况下,不需要在进程之外托管CLR部分。这就是混合模式DLL的意义所在。然后,如果这是遗留代码,您可能会遇到复杂的运行时依赖关系的混合,我们可以说,这些依赖项可能会发生冲突。
进一步思考:
如果我正确理解,您可以选择重新编译所有源(只是不触及遗留代码基?)。如果是这样的话,请确保所有代码都是针对运行库库的相同版本(想想Service )和类型(静态和动态/多线程/调试)编译的。
在检查其他路径时,请注意潜在的冲突依赖关系
https://stackoverflow.com/questions/8331825
复制相似问题