Связать динамическую общую библиотеку в Linux — неопределенная ссылка на функцию

Я знаю, что есть много вопросов, связанных с разделяемыми библиотеками в Linux, но, может быть, потому, что я устал от тяжелого дня, пытаясь создать простую динамическую библиотеку в Linux (в Windows это заняло бы менее 10 минут), я не могу найти что происходит в этом случае. Итак, я пытаюсь создать библиотеку, которую нужно связать во время сборки и использовать во время выполнения (другими словами, не статическую библиотеку, не библиотеку для встраивания в исполняемый файл). На данный момент он содержит простую функцию. Это мои файлы:

1.

// gugulibrary.cpp
// This is where my function is doing its job

#include "gugulibrary.h"

namespace GuGu {
    void SayHello() {
        puts("Hello!");
    }
}

2.

// gugulibrary.h
// This is where I declare my shared functions
#include <stdio.h>

namespace Gugu {
    void SayHello();
}

3.

// guguapp.cpp
// This is the executable using the library
#include "gugulibrary.h"

int main() {
    GuGu::SayHello();
    return 0;
}

Вот как я пытаюсь построить свой проект (и я думаю, что это неправильно):

gcc -Wall -s -O2 -fPIC -c gugulibrary.cpp -o gugulibrary.o
ld -shared -o bin/libGugu.so gugulibrary.o
gcc -Wall -s -O2 guguapp.cpp -o bin/GuGu -ldl
export LD_LIBRARY_PATH=bin

Это сохраняется как файл .sh, который я щелкаю и запускаю в терминале. Ошибка, которую я получаю при попытке связать библиотеку, такова:

/tmp/ccG05CQD.o: In function `main':
guguapp.cpp:(.text.startup+0x7): undefined reference to `SayHello'
collect2: ld returned 1 exit status

И тут я теряюсь. Я хочу, чтобы библиотека находилась в той же папке, что и исполняемый файл, и, возможно, мне нужен какой-то файл символов/определений или что-то еще, что я не знаю, как создать. Спасибо за вашу помощь!


person ali    schedule 03.01.2013    source источник
comment
Похоже, вам не хватает -lGugu   -  person William Pursell    schedule 04.01.2013
comment
Почему gcc? Почему не g++?   -  person Arun    schedule 04.01.2013
comment
ХОРОШО. но я не думаю, что это решит проблему. Спасибо, в любом случае!   -  person ali    schedule 04.01.2013
comment
Кроме того, неясно (мне), в чем смысл extern C, когда используются не-C конструкции, такие как namespace...   -  person Arun    schedule 04.01.2013


Ответы (2)


Вы несовместимы со своим ГуГу, там тоже бегают Гугу, это нужно сделать консистентным, тогда работает (По крайней мере на моем компе какие-то Гугу сейчас)

person pbhd    schedule 03.01.2013
comment
и, конечно же, нужно добавить libGugu.so: g++ -Wall -s -O2 guguapp.cpp bin/libGugu.so -o GuGu -ldl - person pbhd; 04.01.2013
comment
Вы имеете в виду, что я не могу просто создать файл .so для исполняемого файла, поместить его в тот же каталог и вуаля? - person ali; 04.01.2013
comment
Нет, вы также можете сделать это так: gcc -Wall -s -O2 -fPIC -c gugulibrary.cpp -o gugulibrary.o ld -shared -o bin/libGugu.so gugulibrary.o gcc -Wall -s -O2 guguapp.cpp -Lbin -lGugu -o GuGu -ldl Обратите внимание, что вам нужно опустить .soextension, чтобы заставить его работать, - person pbhd; 04.01.2013
comment
Почти готово. Теперь я получаю ошибку поиска символов при выполнении приложения с использованием библиотеки (./GuGu). - person ali; 04.01.2013
comment
... что было исправлено добавлением extern C - person ali; 04.01.2013
comment
Спасибо! Что именно вы подразумеваете под непоследовательным? В Windows вы можете создать dll и использовать ее из той же папки, что и исполняемый файл. В Linux файлы .so хранятся в папке usr/lib или другой папке файловой системы, как libLibName.so.1.0 или с подобным именем. Это единственный способ? - person ali; 04.01.2013
comment
Нет, просто добавьте -L. чтобы связать его с текущим каталогом и сделать что-то вроде export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH - person pbhd; 04.01.2013
comment
Под непоследовательным я имел в виду, что вы иногда пишете вторую Г в Гугу с большой буквы, иногда нет - person pbhd; 04.01.2013

В вашем файле C++ GuGu::SayHello объявлен как символ C++. В заголовке вы заключаете его в блок extern "C". На самом деле это не определено, так как вам не разрешено использовать синтаксис C++ (namespace) в этом контексте. Но я предполагаю, что компилятор игнорирует пространство имен и генерирует имя символа C «SayHello». Очевидно, что такая функция никогда не определялась вашей библиотекой. Удалите биты extern "C", потому что ваш API, как определено, все равно не может использоваться из C.

person Andy Ross    schedule 03.01.2013
comment
Спасибо. Это что-то исправило, но проблема осталась: ошибка при загрузке общих библиотек: bin/libGuGu.so: невозможно открыть общий объектный файл: нет такого файла или каталога - person ali; 04.01.2013
comment
Каталог, содержащий libGuGu.so, должен появиться в вашем LD_LIBRARY_PATH. - person Andy Ross; 04.01.2013