Boost.Extension Tutorial 1 - Problem
-
Hi,
Ich bin ein totaler Anfänger, was die Boost-Bibliotheken betrifft und wollte jetzt Boost.Extension verwenden, um ein Plugin-basiertes Programm zu schreiben.
Nachdem ich mich durch die Installation der Boost-Bibliotheken gekämpft hatte, wollte ich Tutorial 1 zu Extension ausprobieren:
[url]http://boost-extension.redshoelace.c...als.tutorial01 [/url]Also habe ich die folgenden Dateien & Ordner angelegt:
shared_test/
..|
..+- Jamroot
..+- tutorial_1/
.........|
.........+- hello_world.cpp
.........+- main.cppJamroot sieht so aus:
import type : change-generated-target-suffix ; import type : change-generated-target-prefix ; type.change-generated-target-suffix SHARED_LIB : : extension ; type.change-generated-target-prefix SHARED_LIB : : lib ; import os ; local BOOST_ROOT = [ os.environ /usr/local/include/boost ] ; project : requirements <include>#(BOOST_ROOT) : ; lib tutorial_1 : tutorial_1/hello_world.cpp : <link>shared ; exe tutorial_1_bin : tutorial_1/main.cpp ; install binaries : tutorial_1 tutorial_1_bin ;hello_world.cpp sieht so aus:
#include <iostream> #include <boost/extension/extension.hpp> extern "C" void BOOST_EXTENSION_EXPORT_DECL boost_extension_hello_world (int repetitions) { for (int i = 0; i < repetitions; i++) { std::cout << "Hello, World!" << std::endl; } }Und main.cpp sieht so aus:
#include <iostream> #include <boost/extension/shared_library.hpp> #include <boost/function.hpp> class shared_library; int main() { std::string library_path = "libtutorial_1.extension"; shared_library lib(library_path); if (!lib.open()) { std::cerr << "Library failed to open: " << library_path << std << endl; return 1; } boost::function<void (int)> f(lib.get<void, int>("boost_extension_hello_world")); if (!f) { std::cerr << "Function not found!" << std::endl; return 1; } f(4); }
Jetzt zum Problem: Wenn ich mich im "shared_test"-Ordner befinde und die Dateien mittels
bjam
zu kompilieren versuche, erhalte ich die folgenden Fehlermeldungen:gcc.compile.c++ bin/gcc-4.4.3/debug/tutorial_1/main.o tutorial_1/main.cpp: In function ‘int main()’: tutorial_1/main.cpp:10: error: variable ‘shared_library lib’ has initializer but incomplete type tutorial_1/main.cpp:12: error: expected primary-expression before ‘<<’ token tutorial_1/main.cpp:12: error: ‘endl’ was not declared in this scope tutorial_1/main.cpp:17: error: expected primary-expression before ‘void’ tutorial_1/main.cpp:17: error: expected primary-expression before ‘int’Sieht hier irgendjemand das Problem? Ich bin mir sicher, dass es ein Anfängerfehler ist.

-
Die erste Fehlermeldung sagt aus, dass Du ein Objekt vom Typ shared_library erstellen möchtest, obwohl shared_library unvollständig ist. Das ist auch klar, da Du sie nur forward deklarierst (über main).
Du meintest vermutlich die in boost/extension/shared_library.hpp mit Sicherheit vollständig definierte Klasse boost::extensions::shared_library?
-
Genau diese meinte ich :). Weißt du denn, was ich am Code ändern muss, damit es funktioniert?
-
Also den Fehler für die genannten Fehlermeldungen habe ich mittels Entfernung der Vorwärtsdeklaration und Benutzung des passenden Namespaces gelöst (vielen Dank für die Hilfe!), sodass main.cpp jetzt so aussieht:
[code]#include <iostream> #include <boost/extension/shared_library.hpp> #include <boost/function.hpp> [b]using namespace boost::extensions;[/b] int main() { std::string library_path = "libtutorial_1.extension"; shared_library::shared_library lib(library_path); //... // "std << endl" war ebenfalls fehlerhaft std::cerr << "Library failed to open: " << library_path << [b]std::endl[/b]; //... }[/code]Jetzt kommen aber viel kryptischere Fehlermeldungen:
gcc.compile.c++ bin/gcc-4.4.3/debug/tutorial_1/main.o
gcc.link bin/gcc-4.4.3/debug/tutorial_1_bin
bin/gcc-4.4.3/debug/tutorial_1/main.o: In functionboost::extensions::impl::load\_shared_library(char const*)': /usr/local/include/boost/extension/impl/library_impl.hpp:60: undefined reference todlopen'
bin/gcc-4.4.3/debug/tutorial_1/main.o: In functionboost::extensions::impl::get\_function(void*, char const*)': /usr/local/include/boost/extension/impl/library_impl.hpp:64: undefined reference todlsym'
bin/gcc-4.4.3/debug/tutorial_1/main.o: In functionboost::extensions::impl::close\_shared_library(void*)': /usr/local/include/boost/extension/impl/library_impl.hpp:67: undefined reference todlclose'Könnte der Grund hierfür in einem fehlerhaften Jamfile liegen?
-
Das sind jetzt Linkerfehler. Boost.Extension findet die Funktionen zum Öffnen von shared libraries nicht. Abhilfe würde hier -ldl beim Linken bringen.
Wie (und ob) man das ganze beim Linken der Boost.Extension-Bibliothek (Jamfile) selbst lösen kann, wüsste ich jetzt nicht.
-
Ah, verstehe, dann werden also die dl-Bibliotheken nicht richtig gelinkt. Dann bleibt nur noch die Frage, wie ich das mit meiner bisherigen Methode behoben bekomme. Ich werde es mal ohne Jamfile ausprobieren und schauen, was passiert. Längerfristig werde ich aber wohl wieder auf Bjam zurückgreifen, um das Projekt einfach organisieren zu können.
-
So, ich habe jetzt mal alles per Hand kompilieren lassen. Und zwar mit Hilfe folgender Befehle.
Für die dynamische Bibliothek hello_world.cpp:
sudo g++ -shared -fPIC hello_world.cpp -o libhello.soDann das eigentliche Programm:
sudo g++ -o hello main.cpp -ldlWenn ich das nun ausführe, wird leider nicht die dynamische Bibliothek geladen. Wie ich es in main.cpp gefordert habe, wird dies signalisiert:
Library failed to open: libhello.soKann der Fehler nun noch an einer der beiden Quelldateien liegen, wenn das Kompilieren selber funktioniert hat? Oder kann es durch fehlerhafte Compilerparameter verursacht sein?