Можете ли вы статически связать одно и то же сообщение protobuf с несколькими DLL-библиотеками, и тогда эти библиотеки будут работать вместе? - PullRequest
7 голосов
/ 25 февраля 2010

Мы используем google protobufs для передачи данных по проводам. Серверная сторона вещей похожа на плагин, поэтому некоторые модули, обрабатывающие сообщения protobuf, являются DLL. Некоторые библиотеки DLL зависят от других и используют сообщения других для определения своих собственных сообщений.

Итак, A.DLL имеет a.proto, который генерирует a.pb.h/cc с классом сообщения MsgA. При использовании недокументированной опции dllexport_decl в компиляторе protoc класс сообщения объявляется как экспорт DLL.

Теперь B.DLL зависит от A.DLL, и b.proto также выглядит так:

import "a.proto";
message b 
{
    required int32 some_number = 1;
    required PackageA.MsgA some_a = 2;
}

Наконец, исполняемый файл, который объединяет части, также зависит от сообщения MsgA. Библиотека protobuf была также построена как DLL и связана со всем. Все это строит и запускает.

Но есть Силы Света , которые потребовали, чтобы мы сократили дистрибутив DLL! Итак, я построил модуль A (который представляет собой просто набор сообщений и небольших утилит, которые используют многие другие подключаемые библиотеки DLL) в качестве статической библиотеки вместо библиотеки DLL. B.DLL и исполняемый файл оба связаны с A, и все хорошо - пока.

Поскольку A является статически связанным, MsgA полностью определяется во всех DLL и EXE. Это нормально, потому что все статические данные в сгенерированном коде C ++ являются const. Так что, если в конечном процессе будет несколько копий - все копии идентичны.

Но, когда я запускаю недавно созданный процесс, libproto выдает действительно полезное исключение - Идентификатор файла MsgA уже существует в карте дескрипторов (или что-то в этом роде). Другими словами, тот факт, что существует множество определений для MsgA , является серьезной проблемой.

Итак, наконец, вот вопрос (вопросы):

  • Если бы мы статически связали libproto вместо использования его в качестве DLL, ошибка исчезла бы?
  • Действительно ли безопасно иметь несколько определений MsgA, разбросанных по DLL?

Первое, на что я, вероятно, смогу ответить через несколько дней, как только найду перестройку библиотек protobuf, но второе - немного дальше, чем я знаю. Я также надеюсь получить быстрый ответ «вверх» или «вниз», который может избавить меня от необходимости перекомпилировать прото-библиотеки.

1 Ответ

1 голос
/ 23 апреля 2011

Я использовал протобуферы для RPC по сети (Google тоже делает это - см. Страницу документации). Пока у вас есть похожее определение для каждого, кто использует протобуфер, одно определение будет успешно десериализовать данные, сериализованные другими определениями. Фактически, до тех пор, пока вы не переназначите номера тегов, более старые версии определения буфера протокола могут нормально взаимодействовать с более новыми версиями (если в потоке существуют «обязательные» поля в определении десериализации, это будет успех).

Надеюсь, это поможет.

...