Я получаю несколько ошибок определения и не понимаю, почему.
Я собираю код C с помощью g ++ на Cygwin. Я использую фреймворк для юнит-теста (google test, который является C ++, и поэтому я не использую gcc). Исходный файл модульного теста # включает в себя файл .c (fileA.c), содержащий функцию, которую я хочу выполнить модульным тестом, по сути, делая его расширением указанного файла, и я компилирую исходный файл модульного теста. Тестируемая функция вызывает функции, объявленные в fileB.h и определенные в fileB.c. Это немного похоже на Переопределить вызов функции в C . Я не показываю охрану включения, но по сути урезанный код выглядит так:
fileB.h
typedef void * pClass; // to hide the "class" in the .c file
extern pClass pObject1;
void do_something_with_object( void * );
fileB.c
#include "FileB.h"
typedef struct myclass {
int stuff;
} myclass;
myclass Obj1 = { initial_value };
void *pObj1 = &Obj1;
void do_something_with_object( void *arg) {
// do stuff, casting to myclass and verifying it's the right kind
}
fileA.h
#include "fileB.h"
void myfunc( void );
fileA.c
#include "fileA.h"
void myfunc( void ) {
do_something_with_object( pObj1 );
}
utest_fileA.cpp
#include "../fileA.c"
// google test infrastructure stuff not shown
TEST(testname, testcase) {
myfunc();
}
Символы fileB связаны в статическую библиотеку, которая содержит весь производственный код. Статическая библиотека была скомпилирована с g ++, поэтому проблем с extern "C"
нет. Makefile для статического ссылки на utest_fileA.cpp в этой библиотеке. Все идет нормально. Теперь я хочу предоставить свою собственную поддельную версию do_something_with_object, чтобы я мог следить за тем, что было передано, чтобы myfunc вызывал do_something_with_object с правильным параметром. Я не хочу изменять производственный код только для поддержки этого модульного теста. Итак, я создаю поддельную версию do_something_with_object далее в модуле компиляции для моего источника модульного теста:
static void * myspy;
void do_something_with_object( void * arg) {
myspy = arg;
}
Идея состоит в том, что в модульном тесте будет использоваться поддельное определение, и, поскольку оно имеет определение, оно не будет беспокоиться о его поиске в статической библиотеке, и конфликта не будет. Обычно это работает. Но в случае, с которым я сейчас сталкиваюсь, я получаю несколько ошибок определения для do_something_with_object (), сначала находя поддельную, а затем реальную. Я не вижу ничего отличного от случаев, когда это работает, но явно я что-то упускаю. Что может быть причиной этого? Что я должен искать? Это не удается при попытке связать utest_fileA.o с libMyLib.a. Он использует флаг -static. Я попробовал кое-что, что я предложил, в другом месте в stackoverflow, например -z muldefs, но Cygwin это не понравилось, и я действительно хотел бы понять, что происходит.