Skip to content

Shared (dynamic) OSI library on Windows: missing dllexport for protobuf data symbols #7

@jdsika

Description

@jdsika

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.

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 / _pic targets unchanged)

References

Metadata

Metadata

Assignees

Labels

help wantedExtra attention is neededquestionFurther information is requested

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions