Propagating Nested Exceptions Across DLL Boundaries

Can I throw a nested exception from a function in a DLL and catch it in the calling code?

Propagating exceptions, including nested exceptions, across DLL (dynamically linked library) boundaries is possible but requires careful design.

The main challenge is that the DLL and the calling code might use different memory allocators. If an exception is allocated in the DLL using the DLL's allocator, but then caught and deallocated in the calling code using the calling code's allocator, it can lead to runtime errors or memory corruption.

To safely propagate exceptions across DLL boundaries:

  1. The DLL and the calling code should use the same C++ runtime library, to ensure they use the same memory allocator.
  2. The exception types should be defined in a header file that is shared between the DLL and the calling code, to ensure they have the same definition.
  3. The exception types should have a non-throwing destructor, to avoid the issues with throwing destructors mentioned in the previous answer.
  4. The DLL function should catch any internal exceptions and translate them into error codes or exceptions that are part of the DLL's public interface.

Here's an example:

// DLL.cpp
#include <stdexcept>
#include "SharedTypes.h"

// SharedTypes.h
struct DLLException : std::exception {
  const char* what() const noexcept override {
    return "Exception from DLL"; }
};

extern "C" __declspec(dllexport)
void DLLFunction() {
  try {
    // Some operation that might throw
    throw std::runtime_error{"Internal error"};
  } catch (...) {
    std::throw_with_nested(DLLException{});  
  }
}
// Main.cpp
#include <iostream>
#include "SharedTypes.h"

int main() {
  try {
    DLLFunction();
  } catch (const DLLException& e) {
    std::cout << "Caught DLLException: "
      << e.what() << '\n';
    std::rethrow_if_nested(e);
  } catch (const std::exception& e) {
    std::cout << "Caught nested exception: "
      << e.what() << '\n';
  }
}

In this design, the DLLFunction catches any internal exceptions and wraps them in a DLLException, which is defined in a shared header file. The main function can then catch DLLException and access any nested exceptions.

However, even with this design, there are still potential pitfalls. For maximum portability and safety, it's often better for DLL functions to return error codes instead of throwing exceptions.

Nested Exceptions

Learn about nested exceptions in C++: from basic concepts to advanced handling techniques

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Throwing Non-Exceptions with std::throw_with_nested()
What happens if I pass a non-exception type to std::throw_with_nested()?
Handling Nested Exceptions with Multiple Catch Blocks
Can I handle nested exceptions using multiple catch blocks? If so, in what order are they caught?
Performance Impact of Nested Exceptions
Is there a performance penalty when using nested exceptions compared to regular exceptions?
Propagating Nested Exceptions Across Threads
Can I throw a nested exception from one thread and catch it in another thread?
Throwing Nested Exceptions from Destructors
Is it safe to throw nested exceptions from a destructor?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant