Дополнительные вопросы, добавленные ниже, 4/11/2011
Я разрабатываю кросс-платформенный набор разделяемых библиотек DLL/Sos и тестер программ на С++, хотя я должен иметь возможность поддерживать C. Библиотеки будут поставляться только как объектный код, но программа (и) тестировщика отправит с источником, поэтому наши клиенты могут иметь пример кода. По этой причине я разрабатываю библиотеки для загрузки во время выполнения, то есть динамическое связывание с использованием dlopen()/LoadLibraryA().
Я использую g++ 4.4.3-4 для Umbutu 10.04 и VС++ 2008 для Vista/64 (в 32-разрядном режиме).
Все, кажется, отлично работает в Windows (прямо сейчас). Однако, когда я компилирую на Linux, я получаю некоторые ошибки, которые я не могу понять.
Тестер и библиотека имеют несколько классов, закодированных в нескольких .cpp и .h's. Классы и большинство всего в библиотеке, кроме основных точек входа, находятся в пространстве имен DISCOVER_NS.
Вот краткий очерк проекта:
Во-первых, прием, я сократил кучу имен, чтобы код был более читабельным.
discover.cpp
-
Создает объект класса с указателем на него, называемым MainObject типа DiscoverObject.
-
Имеет внешнюю функцию "C" , которая возвращает объект MainObject программе-вызывателю как void *.
-
DiscoverObject имеет несколько методов и создает экземпляры других классов, найденных в отдельных cpp и .h. Один конкретный метод называется Hello(), который делает то, что вы ожидаете, он печатает тестовое сообщение "привет".
tester.cpp
-
Получает дескриптор библиотеки
-
получает указатель на функцию, возвращающую объект MainObject.
-
Выполняет функцию (указатель) и возвращает возвращенный адрес из void * в DISCOVER_NS:: DiscoverObject * aDiscoverObject.
-
Запустите aDiscoverObject- > Hello().
Я компилирую с помощью:
CC = @g++
gflags = -g3
cflags = -fPIC -Wall -pedantic
lib_linkflags: = -shared -fPIC -lstdС++ -lrt -lpthread -rdynamic
tester_linkflags: = -ldl -lpthread
определяет = -D_linux_ -D_DEBUG -D_IPC_ARCH_INTEL = 1 -D_THREAD_SAFE
Теперь, когда я компилирую, я получаю следующие ошибки: * Tester.cpp: 142: undefined ссылка на `Discover_NS:: DiscoverObject:: hello() '*
Я также получаю кучу других справочных ошибок undefined от find.so, например, например: * discover.so: undefined ссылка на `Discover_NS:: DeviceList:: ~ DeviceList() *
Я попытался сделать практически все в SO extern "C" . Нет разницы.
Я попытался поставить утверждения в файл open.cpp, который выглядит так: extern void Discover_NS:: OtherClass:: method (args); но это дает мне ошибки об ошибках "Объявление за пределами класса не является дефинированием".
Я знаю, что это поможет увидеть код, но мне нужно время, чтобы выпустить что-то маленькое для публикации.
Кто-нибудь может предложить идеи для решения этой проблемы?
Спасибо,
Уэс
Решение Дмитрия было не совсем полным исправлением, но было необходимым элементом в решении. После изучения моего файла makefile я обнаружил пару непреднамеренно дублированных строк, которые я удалил, и два "опечатки", где у меня был неправильный путь для -o, закодированного в этапах компиляции. Сломанные шаги скомпилировали logger.cpp и RemException.cpp:
./common/logger.o : ./common/logger.cpp
$(CC) $(gflags) $(cflags) -c $(defines) -I ./common
-I ./EdgeIO -I ./Discover
-o ./common/Debug/logger.o <+++++++++ path to .o was wrong
./common/logger.cpp 2>&1 | tee ./RemKonTester/logger.ERR
Тогда я нашел реальную ошибку. Я полностью упустил тот факт, что я не собирал весь свой .cpp в каталоге Discover!. Потребовался хороший час, чтобы удалить все nit-pics, но теперь она легко компилируется из make файла.
НОВАЯ ВЕРСИЯ ОРИГИНАЛЬНОГО ВОПРОСА: NOw, что я знаю, что он будет работать через makefile, как я могу говорить Eclipse о том, что делает makefile?
Спасибо, Дмитрий.
Уэс
Ну, моя проблема все еще здесь.
У меня есть компиляция кода с предложениями Дмитрия (@Dmitry). Только они, по-видимому, вызывают отдельную проблему. Я хочу, чтобы мои библиотеки связывались с основной программой тестирования динамически во время выполнения. Добавление -l Discover -l EdgeIO в ссылку получает все, чтобы скомпилировать, но это дает мне статическую привязку.
FYI, неиспользуемые "pi" - это так, что SO имеет в нем число с плавающей запятой и, таким образом, скомпилируется с поддержкой с плавающей запятой. Требуется, если вызывающий абонент когда-либо хочет использовать числа с плавающей запятой. Кто-нибудь получил лучший способ заставить g++ скомпилировать с включенной плавающей запятой?
После исправления многих ошибок Дмитрий помог мне найти, теперь я получаю этот вывод:
make
./Discover/dllmain.cpp: In function ‘void InitalizeLibraryServices()’:
./Discover/dllmain.cpp:175: warning: unused variable ‘pi’
./EdgeIO/dllMain.cpp: In function ‘void InitalizeLibraryServices()’:
./EdgeIO/dllMain.cpp:158: warning: unused variable ‘pi’
linking RemKonTester
gflags = -g3
tstlinkflags = -ldl -lpthread
defines = -D__linux__ -D_DEBUG -D_IPC_ARCH_INTEL=1 -D_THREAD_SAFE
./RemKonTester/Debug/RemKonTester.o: In function `main':
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:81: undefined
reference to `RemKon_EdgeIO::EdgeIoObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:111: undefined
reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:116: undefined
reference to `RemKon_Discover::DiscoverObject::SetLogLevel(unsigned int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:117: undefined
reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:118: undefined
reference to `RemKon_Discover::DiscoverObject::LocalIpAddress(int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:122: undefined
reference to `RemKon_Discover::DiscoverObject::RegisterCallback(bool(*)
(void*), void*)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:123: undefined
reference to `RemKon_Discover::DiscoverObject::Search()'
collect2: ld returned 1 exit status
Я получаю тот же набор сообщений об ошибках из Eclipse.
RemKonTester.cpp содержит все .h, где объявляются эти элементы. Я пробовал их с объявлениями extern "C" , а не.
Надеясь на помощь,
Уэс