异常在动态加载的 DLL 中不起作用

问题描述 投票:0回答:1

上下文:我正在开发的 C++ 应用程序的前端是一个动态加载的 DLL,因此可以在不重新编译主应用程序的情况下切换不同的前端(例如,可以有一个使用 Ncurses,一个使用 Raylib,并且要从一种更改为另一种,您所需要做的就是告诉程序 DLL 在哪里)。头文件提供了一个Frontend类,所有前端都必须继承该类,这样大家就知道前端需要具备哪些功能。

问题:DLL 中抛出的异常无法正常工作。当 DLL 中抛出异常时,程序不会立即停止并打印堆栈跟踪,而是挂起大约 3 秒,然后静静地停止。

完全缺乏错误信息使得开发变得非常困难。如何才能让异常情况正常工作?我只是动态加载错误吗?

我使用的是 Windows 11。

如何重现此错误(或缺少错误):

文件结构:
- dll
----- 接口.h
----- import_me.cpp
----- import_me.dll
- 主要.cpp
- CMakeLists.txt

接口.h:

class Interface {
    public:
        virtual void say_hello() = 0;
        virtual void throw_exception() = 0;
};

导入_me.cpp:

#include "interface.h"
#include <iostream>

class ImportMe : public Interface {
    public:
        void say_hello() override {
            std::cout << "Hello from ImportMe!" << std::endl;
        }
        void throw_exception() override {
            throw std::runtime_error("Exception from ImportMe!");
        }
};

extern "C" __declspec(dllexport) Interface* create_ImportMe() {
    return new ImportMe();
}

main.cpp:

#include "dlls/interface.h"
#include <iostream>
#include <windows.h>

// got this from chatGPT so it may not be standard procedure
// basically it's just creating a type of function that returns a pointer to an Interface
typedef Interface* (*create_ImportMe_t)();

Interface* load_ImportMe(const char * name) {
    HMODULE dll = LoadLibrary(name);
    
        // create one of those Interface-grabbing functions (it will be an ImportMe)
    create_ImportMe_t create_ImportMe = (create_ImportMe_t)GetProcAddress(dll, "create_ImportMe");
        // call it and return the pointer to the ImportMe
    return create_ImportMe();
}

int main() {
        // DLL address is hardcoded, but obviously in the real thing it's given by the user.
        // this is the path relative to silent_errors/build/Debug, where main.exe ends up when built with CMake.
    Interface* in = load_ImportMe("../../dlls/import_me.dll");
    in->say_hello();
    in->throw_exception();
    return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.4...3.27.1)
project(silent_errors)
add_executable(silent_errors main.cpp)

我使用cmake构建main.cpp,并使用

g++ -shared -o import_me.dll import_me.cpp

将import_me.cpp编译为DLL

当我运行 main.exe 时,我希望得到类似的信息:
> 主程序
来自 ImportMe 的您好!
RuntimeException:来自 ImportMe 的异常!

但我得到的是:
> 主程序
来自 ImportMe 的您好!
<3 second pause>

一些可能有用的信息: 我尝试使用 CMake 构建 DLL,以防编译器差异导致问题,我只是收到一个弹出窗口,显示:“调试错误!已调用 abort()”,然后程序挂起并崩溃就像 g++ 一样。

c++ cmake g++ dllimport dllexport
1个回答
0
投票

只有当所有模块使用相同的 C++ 运行时,才可能跨 DLL 边界抛出 C++ 异常,在这种情况下,它们也共享一个堆。但这可能会成为维护负担,特别是当涉及多个供应商的库时,因此通常不鼓励这样做。我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.