Сгенерировать DLL, использующую буферы протокола

#c #dll #protocol-buffers

#c #dll #протокол-буферы

Вопрос:

Я работаю над проектом C (VS2017), в котором используется созданный мной тип protobuf.

Однако для этого проекта требуется .dll указанный тип protobuf. __declspec( dllexport ) В объявлении каждого класса по умолчанию нет, и я прочитал в Интернете, что их можно добавить, сгенерировав объект protobuf с помощью этой командной строки:

 --cpp_out=dllexport_decl=MY_EXPORT_MACRO:output/directory
  

Никто не объяснил, что MY_EXPORT_MACRO это такое и как его определить. Когда я впервые сгенерировал свои объекты protobuf, я использовал самую простую строку, и она сработала:

 protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/my_file.proto
  

Что и где MY_EXPORT_MACRO и / или есть другой способ сделать мои файлы protobuf .dll совместимыми?

Ответ №1:

Вы знаете о __declspec( dllimport ) also, правильно? Какой самый простой способ использовать одно и то же определение типа при сборке DLL (с dllexport аннотациями) и в клиентах DLL (с dllimport аннотациями)?

Наличие макроса для переключения аннотации является чрезвычайно распространенной практикой при разработке DLL Win32 всех видов, а не только для библиотек protobuf.

Обычно определение выполняется следующим образом:

 #if BUILD_DLLX
#  define DLLX_API __declspec(dllexport)
#else
#  pragma comment('lib', 'dllx.lib')
#  define DLLX_API __declspec(dllimport)
#endif
  

И затем вы должны использовать --cpp_out=dllexport_decl=DLLX_API:$DST_DIR , чтобы сгенерированные заголовочные файлы были DLLX_API вставлены в нужные места. Затем создайте DLL с /DBUILD_DLLX помощью so, чтобы она экспортировала типы и функции.

Потребители библиотеки DLL могут #include использовать один и тот же файл заголовка, и при отсутствии /DBUILD_DLLX в их конфигурации проекта они получат импорт.

Комментарии:

1. Спасибо за информативный ответ! Однако, куда идет этот фрагмент кода?

2. @JessicaChambers: в заголовочном файле для DLL файл содержит все типы и прототипы функций, экспортируемых DLL. Он должен быть #include общим как в собственном коде DLL, так и в коде, использующем DLL.

3. Спасибо за этот ответ, кто-нибудь знает, есть ли способ сказать протоколу добавить #include то, что определяет DLLX_API непосредственно в сгенерированных заголовках? Я огляделся, но ничего не нашел.