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

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

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

#using <mydotnet.dll>

dll的存在是在编译时测试的,也是在运行时测试的。 如果在运行时未找到 dll,则会抛出未处理的异常:

未处理的异常:System.IO.FileNotFoundException:无法加载文件或程序集 'mydotnet,Version=1.0.0.0,Culture=neutral,PublicKeyToken=n ull' 或其依赖项之一。该系统找不到指定的文件。 在主要(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 中使用它,它在任何代码 运行 之前工作,我无法捕获异常。 另一方面,如果我只在不同的编译单元中使用它,例如在不同的 class 中,问题只会在我实例化此 class 时出现,我将能够捕获例外。 如果缺少 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();
    }
};

==========================================