How can I use Boost.Log across DLL boundaries?

I am trying to integrate Boost.Log in a fairly large application that is composed of a main application that dynamically loads plugins from DLLs. The initial idea was to pass a logging source to plugins so that they can add log messages. However, as soon as code from a DLL tries to log a message to the provided source, the application crashes with an access violation.

Approach 1

The following minimal example illustrates the problem:

int main(int argc, char* argv[])
{
    boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;

    // This is okay
    BOOST_LOG_SEV(logger, boost::log::trivial::info) << "From main()";

    // This crashes
    logFromDll(logger);

    return 0;
}

Where logFromDll is defined in a separate (DLL) project:

Dll.cpp

TESTDLL_API void logFromDll(boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> &logger)
{
    BOOST_LOG_SEV(logger, boost::log::trivial::info) << "From dll";
}

As stated above, this crashes with an access violation in logFromDll (compiled with visual studio 2010).

Approach 2

Boost.Log provides a mechanism for "global storage" of logging sources:

Having declared a global logger, one can be sure to have a thread-safe access to this logger instance from any place of the application code. The library also guarantees that a global logger instance will be unique even across module boundaries.

Sounds exactly like what I need. So I set up the following example:

Logger.h

BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level>)

Main.cpp

int main(int argc, char* argv[])
{
    boost::log::add_console_log
    (
        std::clog,
        boost::log::keywords::format = 
        (
            boost::log::expressions::stream << "[Custom format] " << boost::log::expressions::smessage  
        )
    );

    BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info) << "From main()";

    logFromDll();

    return 0;
}

Dll.cpp

TESTDLL_API void logFromDll()
{
    BOOST_LOG_SEV(my_logger::get(), boost::log::trivial::info) << "From dll";
}

This does not crash, but yields the following output:

[Custom format] From main() 
[2014-06-19 10:22:28.435366] [0x00000233] [info]    From dll

That is, the custom formatting that I set up in main.cpp is only applied when I log from the main project. Any logging from the DLL project is formatted using the default format.

So, how can I perform logging across DLL boundaries in a way that all (formatting) options I set up in the main project are applied correctly?

I've figured out what the problem was. The documentation for Boost.Log states that:

If your application consists of more than one module (e.g. an exe and one or several dll's) that use Boost.Log, the library must be built as a shared object. If you have a single executable or a single module that works with Boost.Log, you may build the library as a static library.

I was using Boost.Log as a static library. Building boost with shared linkage and using that in my project resolved the problem.

How can I use Boost.Log across DLL boundaries? - c++ - android, I am trying to integrate Boost.Log in a fairly large application that is composed of a main application that dynamically loads plugins from DLLs. The initial idea  In addition to the obvious benefit of preventing the possibility of memory leaks and vastly simplifying the client code, smart pointer objects remember their associated deleter, thus guaranteeing that the memory will be correctly deallocated, even across module boundaries. If you're C++11, use std::shared_ptr; otherwise, you can use Boost's shared_ptr.

Not really an answer directly to your question

Personally I think you are asking the DLL to do too much. In general my approach logging from DLLs has been to remove the logging peculiarities to the application by providing a simple callback function to the DLL.

Usually the form some variant of:

std::function<void (DLL::LogLevel, const char*, ...)> logFunc;

It's up to the application to provide a correct translation to its own service.

boost::bind and boost::function across DLL boundaries?, I understand that when using DLLs, we have certain restrictions such as: 1) Memory should be new-ed and deleted in the same memory space. Potential Errors Passing CRT Objects Across DLL Boundaries. When you pass C Run-time (CRT) objects such as file handles, locales, and environment variables into or out of a DLL (function calls across the DLL boundary), unexpected behavior can occur if the DLL, as well as the files calling into the DLL, use different copies of the CRT libraries.

To have completed solution just add #define BOOST_LOG_DYN_LINK into described logger.h before BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT and include logger.h into application/dll source files.

Did C++11 address concerns passing std lib objects between , One of my major complaints about C++ is how hard in practice it is to pass std library objects outside of dynamic library (ie dll/so) boundaries. The std library is  c++ - lboost - passing objects across dll boundaries Boost logger linking issue (3) I am writing a program which uses Boost libraries.

Visual C++ change history 2003, Don't pass CRT (C Runtime) or C++ Standard Library (C++ Standard including DLLs, compiled by using different versions of the compiler. For more information, see Potential Errors Passing CRT Objects Across DLL Boundaries. ldexp , lgamma , llrint , llround , log , log10 , log1p , log2 , lrint , lround  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more

Configuring and building the library - 1.66.0, If your application consists of more than one module (e.g. an exe and one or several dll's) that use Boost.Log, the library must be built as a shared object. Hi, I'm running the call stack analysis and i've found that a function in a dll is responsible for a lot of the used time. However, I can't see the call stack analysis across the dll boundary.

[PDF] Boost.Log v2, Boost.Log v2. XML to PDF by RenderX XEP XSL-FO Formatter, visit us at consists of more than one module (e.g. an exe and one or several dll's) that use Boost. the user sees an error message as a tool-tip notification over the application icon in similar to std::map, so the add_* methods accept an attribute name string  I have written an article about using C++11's custom deleter facilities of unique_ptr to pass objects through DLL boundaries (or shared object libraries in Linux). The method described in the article do not "pollute" the unique_ptr signature with the deleter.