Skip to content

Commit ad0aa59

Browse files
jll63claude
andcommitted
add samples/windll: minimal dllvar mechanism example
Shows the minimal pattern for sharing a registry state across an exe/DLL boundary on Windows using the dllvar policy: - shared.hpp: defines BOOST_OPENMETHOD_EXPORT/IMPORT_DEFAULT_REGISTRY based on WINDLL_OWNER, declares Animal/Dog and a speak() method - main.cpp: defines WINDLL_OWNER (dllexport), loads the plugin at runtime before initialize(), asserts cross-module dispatch works - plugin.cpp: no WINDLL_OWNER (dllimport), adds the Dog-specific overrider via static constructor - CMakeLists.txt: no circular dependency - the exe does not link against the plugin import lib; LoadLibraryA loads the DLL before initialize() Non-Windows: both TUs compiled into a single executable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ae3e976 commit ad0aa59

5 files changed

Lines changed: 112 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,9 @@ if (BOOST_OPENMETHOD_BUILD_TESTS)
220220
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
221221
add_subdirectory(doc/modules/ROOT/examples)
222222
endif ()
223+
224+
# Samples
225+
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
226+
add_subdirectory(samples/windll)
227+
endif ()
223228
endif ()

samples/windll/CMakeLists.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Copyright (c) 2018-2025 Jean-Louis Leroy
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# See accompanying file LICENSE_1_0.txt
4+
# or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
# Illustrates the dllvar mechanism: the exe owns (exports) the registry state;
7+
# the DLL imports it, contributing overriders that are consolidated by
8+
# initialize() before first use.
9+
#
10+
# On non-Windows both compilation units are linked into a single executable.
11+
12+
if (WIN32 OR CYGWIN)
13+
# Exe exports the registry state and loads the plugin at runtime.
14+
add_executable(windll_main main.cpp)
15+
target_compile_definitions(windll_main PRIVATE WINDLL_OWNER)
16+
set_target_properties(windll_main PROPERTIES ENABLE_EXPORTS ON)
17+
target_link_libraries(windll_main PRIVATE Boost::openmethod)
18+
19+
# DLL imports the registry state from the exe.
20+
add_library(windll_plugin SHARED plugin.cpp)
21+
target_link_libraries(windll_plugin PRIVATE Boost::openmethod windll_main)
22+
set_target_properties(windll_plugin PROPERTIES ENABLE_EXPORTS ON)
23+
24+
# windll_main loads windll_plugin at runtime; build both before testing.
25+
add_custom_target(windll_all ALL DEPENDS windll_main windll_plugin)
26+
27+
add_test(
28+
NAME windll
29+
COMMAND windll_main
30+
WORKING_DIRECTORY $<TARGET_FILE_DIR:windll_main>)
31+
else()
32+
# Non-Windows: single executable, no DLL decoration needed.
33+
add_executable(windll_main main.cpp plugin.cpp)
34+
target_compile_definitions(windll_main PRIVATE WINDLL_OWNER)
35+
target_link_libraries(windll_main PRIVATE Boost::openmethod)
36+
37+
add_test(NAME windll COMMAND windll_main)
38+
endif()

samples/windll/main.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
// This module owns the registry state (WINDLL_OWNER -> dllexport).
7+
#define WINDLL_OWNER
8+
#include "shared.hpp"
9+
#include <boost/openmethod/initialize.hpp>
10+
#include <cassert>
11+
#include <string>
12+
#ifdef _WIN32
13+
#include <windows.h>
14+
#endif
15+
16+
using namespace boost::openmethod;
17+
18+
BOOST_OPENMETHOD_CLASSES(Animal, Dog);
19+
BOOST_OPENMETHOD_OVERRIDE(speak, (virtual_ptr<Animal>), const char*) { return "?"; }
20+
21+
int main() {
22+
#ifdef _WIN32
23+
// Load plugin before initialize() so its static constructors register
24+
// the Dog overrider into the shared registry state.
25+
LoadLibraryA("windll_plugin.dll");
26+
#endif
27+
initialize();
28+
29+
Dog d;
30+
assert(speak(virtual_ptr<Dog>::final(d)) == std::string("woof"));
31+
Animal a;
32+
assert(speak(virtual_ptr<Animal>::final(a)) == std::string("?"));
33+
}

samples/windll/plugin.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
// This module imports the registry state from the exe (no WINDLL_OWNER).
7+
#include "shared.hpp"
8+
9+
using namespace boost::openmethod;
10+
11+
BOOST_OPENMETHOD_CLASSES(Animal, Dog);
12+
BOOST_OPENMETHOD_OVERRIDE(speak, (virtual_ptr<Dog>), const char*) { return "woof"; }

samples/windll/shared.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2018-2025 Jean-Louis Leroy
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// See accompanying file LICENSE_1_0.txt
4+
// or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
#pragma once
7+
8+
// Define WINDLL_OWNER in the module that owns (exports) the registry state.
9+
// All other modules that link against it automatically import it.
10+
#ifdef _WIN32
11+
# ifdef WINDLL_OWNER
12+
# define BOOST_OPENMETHOD_EXPORT_DEFAULT_REGISTRY
13+
# else
14+
# define BOOST_OPENMETHOD_IMPORT_DEFAULT_REGISTRY
15+
# endif
16+
#endif
17+
18+
#include <boost/openmethod.hpp>
19+
20+
struct Animal { virtual ~Animal() = default; };
21+
struct Dog : Animal {};
22+
23+
BOOST_OPENMETHOD_CLASSES(Animal, Dog);
24+
BOOST_OPENMETHOD(speak, (boost::openmethod::virtual_ptr<Animal>), const char*);

0 commit comments

Comments
 (0)