我继承了一个旧的MFC / Win32 C ++应用程序,他的源代码我不应该编辑。
此MFC应用程序需要托管旧的MFC / Win32 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 / Win32应用程序遇到“未处理的异常。”
我感觉我可能需要以某种方式在单独的进程中托管CLR才能够创建对象。这是正确的想法吗?或者我完全不在这里了?
代码编译时间,这只发生在运行时。
有什么想法吗?
以下是我尝试运行的代码示例:
MFC / Win32 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文件,那我怎么不接收链接器错误?
答案 0 :(得分:2)
你确定WrapperClass::FunctionToCall()
的实现没有抛出异常吗?看起来你正在缓存CLR对象的内存位置,然后尝试调用其中一个成员。我认为CLR可以随意移动对象,因此您可能正在尝试使用已移动的对象。
如果将WrapperClass::FunctionToCall()
的实现更改为简单的(即创建CLR对象,调用成员函数),那么仍然会得到相同的未处理异常吗?
更新:CPPCLIProject中哪个类 - CPPCLIClass?假设这个项目代表C ++ / CLI DLL,听起来好像它无法在需要调用你的类时找到加载它的程序集。
磁盘上的此程序集相对于应用程序的其余部分在哪里?如果你的根EXE是不受管理的(它听起来像是MFC / Win32),那么CLR会在EXE的目录和GAC中查找以加载程序集(我不认为它在路径中看起来,但我对此并不积极。)
因此,如果CPPCLIProject与EXE不在同一目录中,那可能是您的问题。
答案 1 :(得分:1)
你最好的选择是
try/catch
...)这个想法是将'未知异常'转换为'已知异常'。
通常情况下,没有必要将CLR部分托管在流程之外。这就是混合模式DLL的意义所在。然后,如果这是遗留代码,您可能会遇到运行时依赖项的复杂混合,我们可以说,这可能会发生冲突。
进一步的想法:
如果我理解正确,您可以选择重新编译所有来源(只是不触及旧版代码库?)。如果是这样,请确保所有代码都是针对相同版本(想想Service Pack)编译的,并键入(认为Static vs Dynamic / Multithread / Debug)运行时库。
在检查其他途径时,请注意
上可能存在冲突的依赖关系