首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在旧的MFC/ when 32应用程序上使用C++互操作时遇到错误

在旧的MFC/ when 32应用程序上使用C++互操作时遇到错误
EN

Stack Overflow用户
提问于 2011-11-30 19:35:30
回答 2查看 419关注 0票数 0

我继承了一个旧的MFC/Win32 32 C++应用程序,它是我不应该编辑的源代码。

此MFC应用程序需要承载一个旧的MFC/Win32 32 C++ DLL。此DLL还试图通过混合模式包装器对托管C++/CLI DLL进行函数调用。我知道这听起来有点让人困惑,下面是我的意思的图表:

代码语言:javascript
复制
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

代码语言:javascript
复制
#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
}

混合模式包装器类

代码语言:javascript
复制
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

代码语言:javascript
复制
bool CPPCLIClass::FunctionToCall(UInt32 ui32)
{
    if (ui32 == 42)
    {
        return true;
    }
}

更新:--我已经设法把一个真正的异常从程序中引出来了。我现在收到了一个System.IO.FileNotFound异常,并提供了其他信息,声明:

代码语言:javascript
复制
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文件上链接,那么我怎么会不接收链接器错误呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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位于同一个目录中,这可能是您的问题。

票数 2
EN

Stack Overflow用户

发布于 2011-11-30 19:42:15

你最好的选择是

  • 在调试器下运行(将带有调试信息的附加DLL添加到调试会话中)
  • 对所有(第一次机会)异常启用中断。
  • 跟踪/断言所有HRESULT代码
  • 通常情况下,试图捕获
    • C++例外(try/catch.)
    • Windows结构化异常(IIRC _try/_catch,但见MSDN)

其想法是将“未知异常”转换为“已知异常”。

通常情况下,不需要在进程之外托管CLR部分。这就是混合模式DLL的意义所在。然后,如果这是遗留代码,您可能会遇到复杂的运行时依赖关系的混合,我们可以说,这些依赖项可能会发生冲突。

进一步思考:

如果我正确理解,您可以选择重新编译所有源(只是不触及遗留代码基?)。如果是这样的话,请确保所有代码都是针对运行库库的相同版本(想想Service )和类型(静态和动态/多线程/调试)编译的。

在检查其他路径时,请注意潜在的冲突依赖关系

  • ATL服务器库
  • MFC库(同样是静态的vs动态的/多线程的/调试的)。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8331825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档