如何处理托管C++ (/CLR) 中 #using 语句中的错误

How can I handle errors in #using statement in managed C++ (/CLR)

本文关键字:#using CLR 语句 错误 何处理 处理 C++      更新时间:2023-10-16

我有一个托管C++项目(使用/CLR 编译),它通过 #using 语句引用 .NET dll,如下所示:

#using <mydotnet.dll>

dll 的存在在编译时进行测试,但也在运行时进行测试。如果在运行时找不到 DLL,则会引发未经处理的异常:

未处理的异常:System.IO.FileNotFound异常:无法加载文件或程序集'mydotnet,版本=1.0.0.0,区域性=中性,公钥令牌=null' 或其依赖项之一。系统找不到指定的文件。 at main(Int32 argc, SByte** argv) 在 _mainCRTStartup()

如何捕获此异常? 它似乎在实际代码之前运行,这是有道理的,但我找不到另一种优雅地结束程序的方法。

编辑:我将代码简化为这样,它无法捕获任何异常:

#using <mydotnet.dll>
int main(int argc, char* argv[])
{
    try
    {
    }
    catch (System::IO::FileNotFoundException^ ex)
    {
    }
    catch (System::Exception ^ex)
    {
    }
    return 0;
}

谢谢罗伊。

据我所知,CLR DLL 是使用 JIT 加载的,因此在第一次使用 DLL 中的代码之前不会加载它,这是异常将引发的地方。尝试在第一次使用 DLL 时放置一个try catch块,这应该会捕获错误。

#using <mydotnet.dll>
...
try{
    // use DLL
} catch (Exception e) {
    // Handle file not found here
}

我终于想通了。感谢您的所有帮助,像您建议的那样自己加载程序集,您可以捕获引发的异常,但它需要使用反射,这是我宁愿避免的事情。

问题是我没有意识到我正在使用的 #using 预处理器只影响编译单元。 由于我在main中使用了它,因此它可以在任何代码运行之前工作,并且我无法捕获异常。另一方面,如果我只在不同的编译单元中使用它,例如在不同的类中,则只有在实例化该类时才会出现问题,并且我将能够捕获异常。如果缺少dll,则将抛出找不到dotnet文件的异常,您可以捕获并处理该异常。

所以像这样的东西有效:

==============  main.cpp ==================
#include "managedclass.h"
int main(int argc, char* argv[])
{
    try
    {
        ManagedClass a;
    }
    catch (System::Exception^ ex)
    {
        //handle exception
    }
    return 0;
}

====================== test.h =================
#pragma once
#using <DotNetLib.dll>
using namespace System;
using namespace System::Text;
using namespace DotNetLib;
class A
{
public:
    A()
    {
        auto foo = gcnew SomeClassFromDotNetLib();
    }
};
==========================================