-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Problem
The shared library target open_simulation_interface (SHARED at CMakeLists.txt L122) cannot be used on Windows (MSVC) because protobuf-generated C++ code does not emit __declspec(dllexport) for global data symbols such as _default_instance_ and descriptor tables.
Observed behavior
When a consumer links against open_simulation_interface.dll, the MSVC linker reports unresolved externals for every protobuf data symbol:
LNK2019: unresolved external symbol "class osi3::SensorView const osi3::_SensorView_default_instance_"
Setting WINDOWS_EXPORT_ALL_SYMBOLS ON on the shared target (as done by asam-osi-utilities) only exports functions — it does not export global data objects. This is a known MSVC limitation.
The osi-cpp documentation itself marks Windows dynamic linking as "NOT RECOMMENDED" with a reference to this protobuf discussion.
Evidence that it is solvable
dSPACE ships pre-built shared OSI libraries for Windows (import .lib + .dll) for their VEOS and SCALEXIO platforms, proving that the dllexport problem has a practical solution.
Proposed fix
Use protoc's dllexport_decl option so that all generated C++ code emits __declspec(dllexport) / __declspec(dllimport) annotations for both functions and data symbols.
1. Define an export macro
Create a header (e.g. osi_export.h):
`cpp
#pragma once
#if defined(_WIN32) || defined(_WIN64)
#ifdef OSI_BUILDING_SHARED
#define OSI_EXPORT __declspec(dllexport)
#else
#define OSI_EXPORT __declspec(dllimport)
#endif
#else
#define OSI_EXPORT attribute((visibility("default")))
#endif
`
2. Pass dllexport_decl to protoc
Replace the current protobuf_generate_cpp call (L73) with a custom protoc invocation that passes:
--cpp_out=dllexport_decl=OSI_EXPORT:<output_dir>
This makes every generated .pb.h wrap exported symbols with OSI_EXPORT.
3. Set the build-time define on the shared target
cmake target_compile_definitions(open_simulation_interface PRIVATE OSI_BUILDING_SHARED)
Consumers that link the import .lib will get __declspec(dllimport) automatically (the default when OSI_BUILDING_SHARED is not defined).
4. Update documentation
Remove or qualify the "NOT RECOMMENDED" note in setting_up_osi_cpp.adoc to explain that with dllexport_decl, Windows shared linking is fully supported.
Impact
- Enables shared OSI on Windows — required for plugin architectures where multiple DLLs in the same process share a single OSI/protobuf runtime
- Eliminates duplicate protobuf descriptor pool crashes caused by static linking into multiple DLLs
- Aligns with what dSPACE already ships commercially
- No impact on static builds (
_static/_pictargets unchanged)
References
- protoc dllexport_decl documentation
- protobuf Google Groups thread on Windows DLL exports
- CMake WINDOWS_EXPORT_ALL_SYMBOLS limitation
- asam-osi-utilities PR #44 — CI coverage for shared OSI linking (Linux/macOS only due to this issue)