Разрешение конфликтов с использованием нескольких статических библиотек в C ++ - PullRequest
3 голосов
/ 08 февраля 2012

У меня есть 2 статические библиотеки от «vendor1» и «vendor2»:

  • vendor1.lib и vendor1.h;
  • vendor2.lib и vendor2.h.

В файле vendor1.h.Там есть следующее объявление:

double Min();

В файле vendor2.h.Там есть следующее объявление:

double Min();

В моем клиентском файле:

include "vendor1.h"  
include "vendor2.h"  
double x = Min();

По умолчанию звонки vendor1.h.Я попытался ввести пространство имен:

   namespace vendor1 {  
    include "vendor1.h"
   }

   namespace vendor2 {  
    include "vendor2.h"
   }

При вызове следующей функции

double xx = vendor2::Min();

Я получаю следующие ошибки компоновщика:

Client.cpp 1> Client.obj: ошибка LNK2019: неразрешенный внешний символ «double __cdecl vendor2 :: Min (void)» (? Min @ vendor2 @@ YANXZ), указанный в функции _wmain 1> c: \ temp \ Client \ Debug \ Client.exe:фатальная ошибка LNK1120: 1 неразрешенная внешность

Как это исправить, не создавая обертки для каждой из оберток?

Ответы [ 2 ]

2 голосов
/ 08 февраля 2012

Если у вас две статические библиотеки с конфликтующими именами, вы не сможете статически связать вашу программу! Статический компоновщик просто найдет первый символ, соответствующий неопределенному символу, и выберет его. Заключение имен в пространство имен не помогает: это изменяет пространство имен, ожидаемое в библиотеке. Вы только что нашли, почему пространство имен это хорошая вещь.

Как решить проблему? Я не знаю о подходе, который основан на стандарте C ++. На практике вы можете сделать что-то: создать динамическую библиотеку, которая перенаправляет ваши конфликтующие функции, но помещает имя в отдельные пространства имен (или использует другие имена). Динамические библиотеки связаны с отдельными статическими библиотеками, то есть в настоящее время конфликт не возникает. Вам, вероятно, также нужно будет избегать того, чтобы лежащие в основе имена были видны из символов в общей библиотеке. Детали того, как это сделать, зависят от компилятора, и я не знаю, кто имеет дело с MSVC ++ для таких вещей.

1 голос
/ 08 февраля 2012

Как насчет упаковки функций в разные пространства имен?

vendor1_wrapper.h :

namespace vendor1 {
    double Min();
}

vendor1_wrapper.cpp :

#include "vendor1_wrapper.h"
#include "vendor1.h"

namespace vendor1 {
    double Min()
    {
        return Min();
    }
}

vendor2_wrapper.h :

namespace vendor2 {
    double Min();
}

vendor2_wrapper.cpp :

#include "vendor2_wrapper.h"
#include "vendor2.h"

namespace vendor2 {
    double Min()
    {
        return Min();
    }
}

Теперь вы можете использовать функциииспользуя пространства имен (ваш клиентский файл):

#include "vendor1_wrapper.h"
#include "vendor2_wrapper.h"

...

vendor1::Min();
vendor2::Min();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...