Три уровня проектных зависимостей обуславливают не все связывание в VC ++ 2008 - PullRequest
0 голосов
/ 13 апреля 2011

1) Решение содержит два проекта. Проект 2 зависит от проекта 1 (отмечен в группе «Зависимости проекта»). Часть классов в проекте 1 объявлена ​​и реализована, но никогда не используется в коде (создается любой экземпляр). Чтобы использовать эти классы в lua они связаны, используя luabind. Функция привязки объявляется как статический метод для каждого класса, который должен быть связан. Он вызывается автоматически с использованием кода в cpp и использует что-то вроде "const bool is_bound = ClassName :: Bind ()". Результаты Buld: статическая библиотека для проекта 1 и исполняемый файл для проекта 2.

Все классы связаны и доступны в сценариях.

2) Я добавил проект 3, в зависимости от проекта 2. Buld-результат проекта 2 - статическая библиотека, а результат сборки проекта 3 - исполняемый. В результате - все или часть классов, определенных в проекте 1, вообще не связаны с двоичными файлами. Проблема в том, что после запуска программы они не связаны и не могут использоваться в скриптах.

Как решить эту проблему и в чем причина? Заранее спасибо.

P.S. Я попытался решить это вручную, используя принудительное связывание путем «имитации использования» (в качестве эксперимента). Я использовал такие функции (я знаю, это ужасно)

template <class T, class A1, class A2>
void ForceLinking()
{
   boost::function<void(A1, A2)> f =
       boost::bind<T>(boost::lambda::constructor<T>(), _1, _2);
}
ForceLinking<ClassName, const string&, bool>();

В результате - часть начала связываться, а другая часть нет.

1 Ответ

0 голосов
/ 16 февраля 2012

Когда Visual Studio связывает EXE или DLL, он имеет тенденцию включать каждый статический объект в основной проект и каждую экспортируемую функцию основного проекта. Затем он отслеживает зависимости в этом проекте и любых добавленных библиотеках.

Он не захватывает статические объекты в ссылочных библиотеках, и это, вероятно, следует назвать ошибкой. Чтобы обойти это, мы должны явно указать нужные объекты в основном проекте. Если это так, вам нужно только сослаться на объектные файлы, а остальное позаботится компоновщик.

Я столкнулся с этой проблемой в Google Test, и решение, которое я узнал, выглядит следующим образом: В каждом затронутом исходном файле проекта lib добавьте:

int LinkFileName() { return 0; }

В любой файл проекта DLL или EXE добавьте:

int linkFileName = LinkFileName();

Это довольно смешно, но работает.

...