2015-05-08 21 views
16

Protokol Tamponları 2.6.1 ve GNU GCC 5.1.0 (Ubuntu 14.10 üzerinde) ile basit bir test uygulaması oluşturmaya çalışıyorum ve aşağıdaki hatalar:google :: protobuf :: internal :: empty_string_ [abi: cxx11] için tanımlanmamış başvuru

/home/ragnar/cpp-tools/gcc-linux/bin/g++ -c "/home/ragnar/cpp-projects/gprotobuf_test/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I/home/ragnar/cpp-tools/libs/linux64/protobuf/include -I. 
/home/ragnar/cpp-tools/gcc-linux/bin/g++ -c "/home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc" -g -O0 -Wall -o ./Debug/messages.pb.cc.o -I. -I/home/ragnar/cpp-tools/libs/linux64/protobuf/include -I. 
/home/ragnar/cpp-tools/gcc-linux/bin/g++ -o ./Debug/gprotobuf_test @"gprotobuf_test.txt" -L. -L/home/ragnar/cpp-tools/libs/linux64/protobuf/lib -lprotobuf 
./Debug/main.cpp.o: In function google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11](): 
    /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/generated_message_util.h:80: 
    undefined reference to google::protobuf::internal::empty_string_[abi:cxx11] 
    /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/generated_message_util.h:81: 
    undefined reference to google::protobuf::internal::empty_string_[abi:cxx11] 
./Debug/messages.pb.cc.o: In function protobuf_AssignDesc_messages_2eproto(): 
    /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:32: 
    undefined reference to google::protobuf::DescriptorPool::FindFileByName(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const 
./Debug/messages.pb.cc.o: In function protobuf_AddDesc_messages_2eproto(): 
    /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:83: 
    undefined reference to google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)) 
./Debug/messages.pb.cc.o: In function my_message::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*): 
    /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:187: 
    undefined reference to google::protobuf::internal::WireFormatLite::ReadString(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) 
./Debug/messages.pb.cc.o: In function my_message::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*) const: 
    /home/ragnar/cpp-projects/gprotobuf_test/messages.pb.cc:247: 
    undefined reference to google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, google::protobuf::io::CodedOutputStream*) 
./Debug/messages.pb.cc.o: In function google::protobuf::internal::WireFormatLite::WriteStringToArray(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*): 
    /home/ragnar/cpp-tools/libs/linux64/protobuf/include/google/protobuf/wire_format_lite_inl.h:749: 
    undefined reference to google::protobuf::io::CodedOutputStream::WriteStringWithSizeToArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char*) 
./Debug/messages.pb.cc.o:(.rodata._ZTV10my_message[_ZTV10my_message]+0x20): 
    undefined reference to google::protobuf::Message::GetTypeName[abi:cxx11]() const 
./Debug/messages.pb.cc.o:(.rodata._ZTV10my_message[_ZTV10my_message]+0x40): 
    undefined reference to google::protobuf::Message::InitializationErrorString[abi:cxx11]() const 
collect2: error: ld returned 1 exit status 
gprotobuf_test.mk:93: recipe for target "Debug/gprotobuf_test" failed 
make[1]: *** [Debug/gprotobuf_test] Error 1 
make[1]: Leaving directory "/home/ragnar/cpp-projects/gprotobuf_test" 
Makefile:4: recipe for target "All" failed 
make: *** [All] Error 2 

/home/ragnar/cpp-araçlar/libs/linux64/protobuf/lib içeren aşağıdaki kütüphaneleri:

option java_package = "my.package"; 

message my_message { 
    required string word = 1; 
    required uint32 number = 2; 
} 
:

libprotobuf.a 
libprotobuf.so.9.0.1 
libprotobuf-lite.a 
libprotobuf-lite.so.9.0.1 
libprotoc.a 
libprotoc.so.9.0.1 

Burada basit messages.proto dosyasıdır

ve ben çalışıyorum kod çalışma almak için:

#include <iostream> 
#include <vector> 
#include <google/protobuf/io/coded_stream.h> 
#include <google/protobuf/io/zero_copy_stream_impl.h> 
#include "messages.pb.h" 

std::vector<unsigned char> encode(google::protobuf::Message & msg) 
{ 
    std::vector<unsigned char> data(msg.ByteSize() + 
    google::protobuf::io::CodedOutputStream::VarintSize32(msg.ByteSize())); 
    google::protobuf::io::ArrayOutputStream array_out(&data[0], data.size()); 
    google::protobuf::io::CodedOutputStream coded_out(&array_out); 
    coded_out.WriteVarint32(msg.ByteSize()); 
    msg.SerializeToCodedStream(&coded_out); 
    return data; 
} 

void decode(const std::vector<unsigned char> & data, google::protobuf::Message & msg) 
{ 
    google::protobuf::io::ArrayInputStream array_in(&data[0] , data.size()); 
    google::protobuf::io::CodedInputStream coded_in(&array_in); 
    google::protobuf::uint32 size; 
    coded_in.ReadVarint32(&size); 
    google::protobuf::io::CodedInputStream::Limit msg_limit = coded_in.PushLimit(size); 
    msg.ParseFromCodedStream(&coded_in); 
    coded_in.PopLimit(msg_limit); 
} 

int main(int argc, char **argv) 
{ 
    my_message in_msg; 
    in_msg.set_word(\"blah blah\"); 
    in_msg.set_number(123); 
    std::vector<unsigned char> data = encode(in_msg); 

    my_message out_msg; 
    decode(data, out_msg); 
    std::cout << \"word: \" << out_msg.word() << \" number: \" << out_msg.number() << std::endl; 
    return 0; 
} 
gcc aşağıdaki seçeneklerle kaynağından inşa edilmiştir

:

ve Protobuf aşağıdaki seçeneklerle kaynağından inşa edilmiştir:

--enable-64it --disable-32bit --enable-shared CXXFLAGS=-m64 -DNDEBUG LDFLAGS=-m64 

Herhangi bir yardım büyük memnuniyetle karşılanacaktır.

cevap

25

Bunun bir C++ ABI sorunu olduğundan şüpheleniyorum. std::string için ABI GCC 5'te değiştirildi (C++ 11 gereksinimleriyle ilgili, ancak C++ 11 kullanmıyor olsanız bile geçerlidir). Bkz:

libprotobuf GCC 4.x veya öncesinde inşa edilmiş, ancak uygulama GCC 5 ile inşa edilirse

https://gcc.gnu.org/gcc-5/changes.html#libstdcxx

libprotobuf kendi arayüzünde std::string kullanması nedeniyle, o zaman, sorunları göreceksiniz. İki seçeneğiniz vardır:

  1. GCC 5 ile libprotobuf'u yeniden oluşturun (ancak şimdi GCC 4 ile oluşturulan tüm uygulamalar libprotobuf'un yeni sürümü ile çalışmaz).
  2. Yukarıdaki bağlantıda açıklandığı gibi -D_GLIBCXX_USE_CXX11_ABI=0 ile uygulama oluşturun. Bu, GCC'yi eski ABI sürümünü kullanmaya zorlayacaktır.
+1

Merhaba, -D_GLIBCXX_USE_CXX11_ABI = 0 öğesinin nerede ekleneceğini söyleyebilir misiniz? Makefile'de 245 satırındaki caffe klasörüne ekledim. Herhangi bir değişiklik yapmıyor gibi görünüyor. Teşekkürler. – awhitesong

5

Ben

writeProto.cpp:(.text+0x2a8): undefined reference to `google::protobuf::internal::VerifyVersion(int, int, char const*)' 
writeProto.cpp:(.text+0x308): undefined reference to `tutorial::AddressBook::AddressBook()' 
writeProto.cpp:(.text+0x3a2): undefined reference to `google::protobuf::Message::ParseFromIstream(std::istream*)' 
writeProto.cpp:(.text+0x463): undefined reference to `google::protobuf::Message::SerializeToOstream(std::ostream*) const' 
writeProto.cpp:(.text+0x4b4): undefined reference to `google::protobuf::ShutdownProtobufLibrary()' 
writeProto.cpp:(.text+0x4c8): undefined reference to `tutorial::AddressBook::~AddressBook()' 
writeProto.cpp:(.text+0x515): undefined reference to `tutorial::AddressBook::~AddressBook()' 

Ben komut satırında bu yazdım ve şimdi kod çalışıyor olarak benzer bir sorun vardı.

c++ writeProto.cpp addressbook.pb.cc `pkg-config --cflags --libs protobuf` 
+0

Bu sorun çözüldü, ama nasıl? –

+2

@MaksimGayduk Protokol Arabelleklerini kullanan bir paketi derlemek için derleyicinize ve bağlayıcıya çeşitli bayraklar iletmeniz gerekir. Protokol Tamponları, bunu yönetmek için pkg-config ile bütünleşir. Eğer pkg-config kuruluysa, bir bayrak listesi almak için bunu başlatabilirsiniz. Ve sonra bunu komut satırına yazınız: C++ my_program.cc my_proto.pb.cc 'pkg-config --cflags --libs protobuf' –

+0

Bu, asıl sorudan ayrı bir sorundur .. ama evet pkg-config normalde en iyisidir burada pratik yap – moof2k

İlgili konular