VC++ Linker Problem...
-
Hallo,
ich habe ein kleines Hello World Projekt in VC++ 2005 expr. (Vista x64 falls das von Bedeutung sein sollte), in dem ich eine externe Lib einbinden möchte (libbotan). Dazu habe ich das libbotan Includeverzeichnis und das Verzeichnis in dem libbotan.lib liegt dem Projekt hinzugefügt, und libbotan zum Linker hinzugefügt.
Hier ist der Quellcode der main.cpp:
#include <botan/botan.h> using namespace Botan; int main(int argc, char *argv[]) { LibraryInitializer init; return 0; }Dabei ist LibraryInitializer eine libbotan Klasse. Wenn ich das ganze nun durchkompilieren will, bekomm ich das:
1>libbotan.lib(es_win32.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__GetCaretPos@4" in Funktion ""private: virtual void __thiscall Botan::Win32_EntropySource::do_fast_poll(void)" (?do_fast_poll@Win32_EntropySource@Botan@@EAEXXZ)".
1>libbotan.lib(es_win32.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__GetCursorPos@4" in Funktion ""private: virtual void __thiscall Botan::Win32_EntropySource::do_fast_poll(void)" (?do_fast_poll@Win32_EntropySource@Botan@@EAEXXZ)".
1>libbotan.lib(es_win32.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__GetInputState@0" in Funktion ""private: virtual void __thiscall Botan::Win32_EntropySource::do_fast_poll(void)" (?do_fast_poll@Win32_EntropySource@Botan@@EAEXXZ)".
1>libbotan.lib(es_win32.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__GetMessageTime@0" in Funktion ""private: virtual void __thiscall Botan::Win32_EntropySource::do_fast_poll(void)" (?do_fast_poll@Win32_EntropySource@Botan@@EAEXXZ)".
1>libbotan.lib(es_win32.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__GetMessagePos@0" in Funktion ""private: virtual void __thiscall Botan::Win32_EntropySource::do_fast_poll(void)" (?do_fast_poll@Win32_EntropySource@Botan@@EAEXXZ)".
1>libbotan.lib(es_capi.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CryptAcquireContextA@20" in Funktion ""public: __thiscall `public: virtual unsigned int __thiscall Botan::Win32_CAPI_EntropySource::slow_poll(unsigned char * const,unsigned int)'::`2'::CSP_Handle::CSP_Handle(unsigned __int64)" (??0CSP_Handle@?1??slow_poll@Win32_CAPI_EntropySource@Botan@@UAEIQAEI@Z@QAE@_K@Z)".
1>libbotan.lib(es_capi.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CryptReleaseContext@8" in Funktion ""public: __thiscall `public: virtual unsigned int __thiscall Botan::Win32_CAPI_EntropySource::slow_poll(unsigned char * const,unsigned int)'::`2'::CSP_Handle::~CSP_Handle(void)" (??1CSP_Handle@?1??slow_poll@Win32_CAPI_EntropySource@Botan@@UAEIQAEI@Z@QAE@XZ)".
1>libbotan.lib(es_capi.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CryptGenRandom@12" in Funktion ""public: void __thiscall `public: virtual unsigned int __thiscall Botan::Win32_CAPI_EntropySource::slow_poll(unsigned char * const,unsigned int)'::`2'::CSP_Handle::gen_random(unsigned char * const,unsigned int)const " (?gen_random@CSP_Handle@?1??slow_poll@Win32_CAPI_EntropySource@Botan@@UAEIQAEI@Z@QBEX0I@Z)".Die Lib selbst findet er, wenn ich sie testweise in den Linkereinstellungen rausnehme, kommen entsprechende andere Fehler.
Die beiden Libs musste ich ignorieren:
msvcrtd.lib;LIBCMT.libDa sonst jede Menge "ist bereits in ... definiert" Fehler kommen.
Kann mir jemand helfen das hinzubekommen? Falls jemand rumprobieren will, die lib gibts hier:
Ist auch einfach zu bauen, geht mit ein paar Klicks.
Danke schonmal im Voraus...
-
Es deutet immer auf massive Fehlkonfiguration hin, wenn Du irgendwelche LIBs ignorieren musst!
Auch hast Du die integration des PSDKs vermutlich nicht ganz vollständig gemacht, sonst würde die ersten Linker-Fehler nicht kommen.
Mach mal:
#pragma comment(lib, "User32.lib") #pragma comment(lib, "Advapi32.lib")
-
Jochen Kalmbach schrieb:
Es deutet immer auf massive Fehlkonfiguration hin, wenn Du irgendwelche LIBs ignorieren musst!
Auch hast Du die integration des PSDKs vermutlich nicht ganz vollständig gemacht, sonst würde die ersten Linker-Fehler nicht kommen.
Mach mal:
#pragma comment(lib, "User32.lib") #pragma comment(lib, "Advapi32.lib")Okay, mit den beiden Libs läuft das Hello World nun

Das mit dem Libs Ignorieren hatte ich eben ein bisschen verwechselt. Im Hello World Projekt ignoriere ich keine Libs, und binde nun nur libbotan, User32.lib und Advapi32.lib ein, und alles läuft problemlos

In meinem eigentlichen Projekt (QT 4.3.4 Projekt) musste ich die Libs ignorieren. Wenn ich das Projekt (noch ohne Botan) durchkompiliere, bekomme ich dort nämlich diese Fehler:
1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) ist bereits in LIBCMT.lib(typinfo.obj) definiert.
1>msvcrtd.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) ist bereits in LIBCMT.lib(typinfo.obj) definiert.Wenn ich die msvcrtd.lib dann Ignoriere, kompiliert er durch, und mein QT GUI-Programm läuft ohne Probleme (immer noch ohne Botan).
Wenn ich jetzt Botan dazu linke (wie im OP beschrieben), kommen die Anfangs genannten undefined references. Jetzt hab ich aber dank dir noch die beiden Libs User32.lib und Advapi32.lib eingebunden, und das Programm kompiliert fehlerfrei

Die msvcrtd.lib muss ich aber weiter ignorieren, da sonst die Fehler oben kommen. In den Projekteinstellungen hab ich für die Laufzeitbibliothek /MT eingestellt, und für MFC "Windows-Standardbibliotheken verwenden" eingestellt.
Also danke für die Hilfe, bis auf die Kleinigkeit mit der ignorierten Lib ist nun alles prima. Einzig die Linker Warnung
"1>LINK : warning LNK4068: /MACHINE nicht angegeben ; Standardwert X86"
bekomm ich noch. Kann ich die ignorieren?
-
Irgendeine LIB (oder mehrere) sind mit den falschen Einstellungen für /MT/MD compiliert!!!
*ALLE* LIBs/DLLs/EXEn *müssen* mit genau den gleichen Einstellungen kompiliert werden, sonst kommt es genau zu diesen Effekten.
Auch kommt es dann oft zu unerwarteten Abstürzen, wenn Du diese Einstellungen nicht korrekt setzt!
-
Ja das hatte ich schon irgendwo gelesen. Ich denke das kommt daher, dass die QT Libs dynamisch gelinkt werden. Hatte das beim Bauen der Qt Sourcen nicht bedacht, aber will das eh nochmal ändern, weil ich nicht immer die Qt DLLs mit rumschleppen will.
Auf jedenfall Danke für die schnelle Hilfe, klappt so weit

Ein kleines Problem hätte ich noch, auch wenn das hier im Forum dann wohl eher Offtopic ist:
Beim bauen des Botan Hello World Programms bekomm ich komische Fehler... der Code dazu ist Copy & Paste von Tutorial PDF (Seite 5, Final Version) und sieht so aus:#include <botan/botan.h> #include <string.h> #include <iostream> #include <fstream> using namespace Botan; int main(int argc, char* argv[]) { std::string passphrase = "test"; std::ifstream infile("test.txt"); std::ofstream outfile("test.txt.crypt"); if (!infile) return 0; LibraryInitializer init; S2K* s2k = get_s2k("PBKDF2(SHA-1)"); s2k->set_iterations(4096); s2k->new_random_salt(8); SecureVector<byte> the_salt = s2k->current_salt(); SymmetricKey master_key = s2k->derive_key(48, passphrase); KDF* kdf = get_kdf("KDF2(SHA-1)"); SymmetricKey key = kdf->derive_key(20, master_key, "cipher key"); SymmetricKey mac_key = kdf->derive_key(20, masterkey, "hmac key"); InitializationVector iv = kdf->derive_key(8, masterkey, "cipher iv"); Pipe pipe(new Fork(new Chain(get_cipher("Blowfish/CBC/PKCS7", key, iv, ENCRYPTION), new DataSink_Stream(outfile)), new MAC_Filter("HMAC(SHA-1)", mac_key))); outfile.write((const char*)the_salt.ptr(), the_salt.size()); pipe.start_msg(); infile >> pipe; pipe.end_msg(); SecureVector<byte> hmac = pipe.read_all(1); outfile.write((const char*)hmac.ptr(), hmac.size()); return 0; }Das oben hab ich eben testweise auch unter linux mit
gcc -lbotan main.cc -o mainkompiliert, da krieg ich die gleichen Fehler wie unter Windows.
Und zwar sagt er mir des öfteren sowas:
main.cc:26: Fehler: keine passende Funktion für Aufruf von »Botan::KDF::derive_key(int, Botan::SymmetricKey&, const char [11])«
/usr/include/botan/pk_util.h:53: Anmerkung: Kandidaten sind: Botan::SecureVector<unsigned char> Botan::KDF::derive_key(Botan::u32bit, const Botan::MemoryRegion<unsigned char>&, const std::string&) const
/usr/include/botan/pk_util.h:55: Anmerkung: Botan::SecureVector<unsigned char> Botan::KDF::derive_key(Botan::u32bit, const Botan::MemoryRegion<unsigned char>&, const Botan::MemoryRegion<unsigned char>&) const
/usr/include/botan/pk_util.h:57: Anmerkung: Botan::SecureVector<unsigned char> Botan::KDF::derive_key(Botan::u32bit, const Botan::MemoryRegion<unsigned char>&, const Botan::byte*, Botan::u32bit) const
/usr/include/botan/pk_util.h:60: Anmerkung: Botan::SecureVector<unsigned char> Botan::KDF::derive_key(Botan::u32bit, const Botan::byte*, Botan::u32bit, const std::string&) const
/usr/include/botan/pk_util.h:62: Anmerkung: Botan::SecureVector<unsigned char> Botan::KDF::derive_key(Botan::u32bit, const Botan::byte*, Botan::u32bit, const Botan::byte*, Botan::u32bit) constoder
main.cc:33: Fehler: »class Botan::SecureVector<unsigned char>« hat kein Element namens »ptr«
main.cc:40: Fehler: »class Botan::SecureVector<unsigned char>« hat kein Element namens »ptr«Die Fehler hab ich jetzt bei vielen Teilen die ich aus dem PDF kopiert habe bekommen. Mach ich da irgendwas komplett falsch, oder wieso findet er Methoden/Objekte nicht, die im PDF doch fröhlich verwendet werden?
Wenn das zu Offtopic ist, kann ich vllt auch nen neuen Thread dafür aufmachen. Jedenfalls danke für die Hilfe.
[edit] hat sich wohl erledigt. nach ein bisschen header durchschauen scheint es wohl so, als ob der code im tutorial schlicht falsch ist, obwohl ich die fehler eher auf mich geschoben hätte.
wenn man statt .ptr() die methode .begin() nutzt, master_key statt masterkey verwendet, und als argument master_key.bits_of() statt master_key nimmt, kompiliert er, und läuft auch problemlos.
ob das cryptographisch/logisch gesehn dann noch stimmt, oder ob die lib dann falsch benutzt wird, kann ich mit meinem begrenzten botan-wissen jedoch nicht sagen.