2

我最近一直在与 Google protobufs 作斗争。我写了一个名为Button.proto.

以下是它的内容:

syntax = "proto3";

package robotjoystick;

message Button {
  string name = 1;
  int32 id = 2;
  uint32 state = 3;
}

我使用此命令成功编译了它(将 $USER 替换为实际计算机用户):

protoc -I=/home/$USER/robotjoystickserver --cpp_out=/home/$USER/robotjoystickserver/proto_classes Button.proto

我正在使用 protobuf 版本3.7.1。我的 *.cpp 文件被调用dumbprrotos.cpp,但由于某种原因它没有编译。这是我的 *.cpp 文件:

// Client side C/C++ program to demonstrate Socket programming 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
// This line was forgotten apparently - https://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found
#include <arpa/inet.h>
// This one was also forgotten - https://www.reddit.com/r/learnprogramming/comments/3tlii5/clinux_why_is_write_or_close_not_declared_in_this/   
#include <unistd.h>
// This is SDL 2.0, the joystick control library
#include <SDL2/SDL.h>
// For Ctrl+C quitting
#include <signal.h>
// for std::end 
//#include <iostream>

// Now we import the header files the protobuf compiler generated.
#include "proto_classes/Button.pb.h"

// This is a standard port
#define PORT 8080

//#include<iostream>
using namespace std;

// For the protobuf generated class.
using namespace robotjoystick;

int main(int argc, char const *argv[]) 
{
    // https://developers.google.com/protocol-buffers/docs/cpptutorial
    // Verify that the version of the library that we linked against is
    // compatible with the version of the headers we compiled against.
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    // Broken method 1
    /*
    const string thename = "blah";
    robotjoystick::Button * thebutton;
    thebutton = new Button();
    thebutton->set_name("john");
    thebutton->set_id(12); 
    */

    // Broken method 2

    const string thename = "blah";
    robotjoystick::Button thebutton;
    thebutton.set_name("john");
    thebutton.set_id(12); 

    return 0; 
} 

我标记的 2 段代码是我试图完成的同一件事的 2 个版本,但两者都抛出相同类型的错误,我不知道如何解释它。我需要做什么才能编译此代码?

我还应该提到我3.7.1在我的主目录中安装了 protobuf(这意味着 protobuf 的 zip 文件被解压到那里然后安装在那里)。

我当前运行代码时得到的错误,确切的方式是,我得到这个错误:

Compiling dumbprotos.cpp

/tmp/cc7HHVQf.o: In function `google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]()':
dumbprotos.cpp:(.text._ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev[_ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev]+0x5): undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]'
/tmp/ccMdby3z.o: In function `AddDescriptors_Button_2eproto()':
Button.pb.cc:(.text+0xa6): undefined reference to `google::protobuf::internal::AddDescriptors(google::protobuf::internal::DescriptorTable*, void (* const*)(), int)'
/tmp/ccMdby3z.o: In function `robotjoystick::Button::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)':
Button.pb.cc:(.text+0x660): undefined reference to `google::protobuf::io::CodedInputStream::ReadTagFallback(unsigned int)'
Button.pb.cc:(.text+0x73f): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccMdby3z.o: In function `robotjoystick::Button::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*) const':
Button.pb.cc:(.text+0x904): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccMdby3z.o: In function `robotjoystick::Button::InternalSerializeWithCachedSizesToArray(unsigned char*) const':
Button.pb.cc:(.text+0xa98): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccMdby3z.o: In function `robotjoystick::Button::GetMetadata() const':
Button.pb.cc:(.text+0x1386): undefined reference to `google::protobuf::internal::AssignDescriptors(google::protobuf::internal::AssignDescriptorsTable*)'
/tmp/ccMdby3z.o: In function `robotjoystick::Button* google::protobuf::Arena::CreateMaybeMessage<robotjoystick::Button>(google::protobuf::Arena*)':
Button.pb.cc:(.text+0x142e): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text+0x144b): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccMdby3z.o: In function `google::protobuf::io::CodedInputStream::ReadVarint32(unsigned int*)':
Button.pb.cc:(.text._ZN6google8protobuf2io16CodedInputStream12ReadVarint32EPj[_ZN6google8protobuf2io16CodedInputStream12ReadVarint32EPj]+0x78): undefined reference to `google::protobuf::io::CodedInputStream::ReadVarint32Fallback(unsigned int)'
/tmp/ccMdby3z.o: In function `google::protobuf::Arena::AllocHook(std::type_info const*, unsigned long) const':
Button.pb.cc:(.text._ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom[_ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom]+0x3d): undefined reference to `google::protobuf::Arena::OnArenaAllocation(std::type_info const*, unsigned long) const'
/tmp/ccMdby3z.o: In function `google::protobuf::internal::ArenaStringPtr::CreateInstance(google::protobuf::Arena*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x23e): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text._ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x25b): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccMdby3z.o: In function `google::protobuf::internal::InitSCC(google::protobuf::internal::SCCInfoBase*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal7InitSCCEPNS1_11SCCInfoBaseE[_ZN6google8protobuf8internal7InitSCCEPNS1_11SCCInfoBaseE]+0x4d): undefined reference to `google::protobuf::internal::InitSCCImpl(google::protobuf::internal::SCCInfoBase*)'
/tmp/ccMdby3z.o: In function `google::protobuf::internal::OnShutdownDestroyMessage(void const*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv[_ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv]+0x14): undefined reference to `google::protobuf::internal::DestroyMessage(void const*)'
Button.pb.cc:(.text._ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv[_ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv]+0x19): undefined reference to `google::protobuf::internal::OnShutdownRun(void (*)(void const*), void const*)'
/tmp/ccMdby3z.o: In function `google::protobuf::internal::InternalMetadataWithArena::default_instance()':
Button.pb.cc:(.text._ZN6google8protobuf8internal25InternalMetadataWithArena16default_instanceEv[_ZN6google8protobuf8internal25InternalMetadataWithArena16default_instanceEv]+0x5): undefined reference to `google::protobuf::UnknownFieldSet::default_instance()'
/tmp/ccMdby3z.o: In function `google::protobuf::internal::InternalMetadataWithArenaBase<google::protobuf::UnknownFieldSet, google::protobuf::internal::InternalMetadataWithArena>::mutable_unknown_fields_slow()':
Button.pb.cc:(.text._ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv[_ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv]+0x15c): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text._ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv[_ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv]+0x176): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccMdby3z.o:(.rodata._ZTVN13robotjoystick6ButtonE[_ZTVN13robotjoystick6ButtonE]+0xb8): undefined reference to `google::protobuf::Message::SpaceUsedLong() const'
collect2: error: ld returned 1 exit status

当我用另一个破碎的场景编译代码时,

const string thename = "blah";
robotjoystick::Button * thebutton;
thebutton = new Button();
thebutton->set_name("john");
thebutton->set_id(12); 

我收到了这个错误:

Compiling dumbprotos.cpp

/tmp/ccaCT7Iy.o: In function `google::protobuf::internal::GetEmptyStringAlreadyInited[abi:cxx11]()':
dumbprotos.cpp:(.text._ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev[_ZN6google8protobuf8internal27GetEmptyStringAlreadyInitedB5cxx11Ev]+0x5): undefined reference to `google::protobuf::internal::fixed_address_empty_string[abi:cxx11]'
/tmp/ccfmvBXP.o: In function `AddDescriptors_Button_2eproto()':
Button.pb.cc:(.text+0xa6): undefined reference to `google::protobuf::internal::AddDescriptors(google::protobuf::internal::DescriptorTable*, void (* const*)(), int)'
/tmp/ccfmvBXP.o: In function `robotjoystick::Button::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)':
Button.pb.cc:(.text+0x660): undefined reference to `google::protobuf::io::CodedInputStream::ReadTagFallback(unsigned int)'
Button.pb.cc:(.text+0x73f): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccfmvBXP.o: In function `robotjoystick::Button::SerializeWithCachedSizes(google::protobuf::io::CodedOutputStream*) const':
Button.pb.cc:(.text+0x904): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccfmvBXP.o: In function `robotjoystick::Button::InternalSerializeWithCachedSizesToArray(unsigned char*) const':
Button.pb.cc:(.text+0xa98): undefined reference to `google::protobuf::internal::WireFormatLite::VerifyUtf8String(char const*, int, google::protobuf::internal::WireFormatLite::Operation, char const*)'
/tmp/ccfmvBXP.o: In function `robotjoystick::Button::GetMetadata() const':
Button.pb.cc:(.text+0x1386): undefined reference to `google::protobuf::internal::AssignDescriptors(google::protobuf::internal::AssignDescriptorsTable*)'
/tmp/ccfmvBXP.o: In function `robotjoystick::Button* google::protobuf::Arena::CreateMaybeMessage<robotjoystick::Button>(google::protobuf::Arena*)':
Button.pb.cc:(.text+0x142e): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text+0x144b): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccfmvBXP.o: In function `google::protobuf::io::CodedInputStream::ReadVarint32(unsigned int*)':
Button.pb.cc:(.text._ZN6google8protobuf2io16CodedInputStream12ReadVarint32EPj[_ZN6google8protobuf2io16CodedInputStream12ReadVarint32EPj]+0x78): undefined reference to `google::protobuf::io::CodedInputStream::ReadVarint32Fallback(unsigned int)'
/tmp/ccfmvBXP.o: In function `google::protobuf::Arena::AllocHook(std::type_info const*, unsigned long) const':
Button.pb.cc:(.text._ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom[_ZNK6google8protobuf5Arena9AllocHookEPKSt9type_infom]+0x3d): undefined reference to `google::protobuf::Arena::OnArenaAllocation(std::type_info const*, unsigned long) const'
/tmp/ccfmvBXP.o: In function `google::protobuf::internal::ArenaStringPtr::CreateInstance(google::protobuf::Arena*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x23e): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text._ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN6google8protobuf8internal14ArenaStringPtr14CreateInstanceEPNS0_5ArenaEPKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x25b): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccfmvBXP.o: In function `google::protobuf::internal::InitSCC(google::protobuf::internal::SCCInfoBase*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal7InitSCCEPNS1_11SCCInfoBaseE[_ZN6google8protobuf8internal7InitSCCEPNS1_11SCCInfoBaseE]+0x4d): undefined reference to `google::protobuf::internal::InitSCCImpl(google::protobuf::internal::SCCInfoBase*)'
/tmp/ccfmvBXP.o: In function `google::protobuf::internal::OnShutdownDestroyMessage(void const*)':
Button.pb.cc:(.text._ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv[_ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv]+0x14): undefined reference to `google::protobuf::internal::DestroyMessage(void const*)'
Button.pb.cc:(.text._ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv[_ZN6google8protobuf8internal24OnShutdownDestroyMessageEPKv]+0x19): undefined reference to `google::protobuf::internal::OnShutdownRun(void (*)(void const*), void const*)'
/tmp/ccfmvBXP.o: In function `google::protobuf::internal::InternalMetadataWithArena::default_instance()':
Button.pb.cc:(.text._ZN6google8protobuf8internal25InternalMetadataWithArena16default_instanceEv[_ZN6google8protobuf8internal25InternalMetadataWithArena16default_instanceEv]+0x5): undefined reference to `google::protobuf::UnknownFieldSet::default_instance()'
/tmp/ccfmvBXP.o: In function `google::protobuf::internal::InternalMetadataWithArenaBase<google::protobuf::UnknownFieldSet, google::protobuf::internal::InternalMetadataWithArena>::mutable_unknown_fields_slow()':
Button.pb.cc:(.text._ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv[_ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv]+0x15c): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAligned(unsigned long)'
Button.pb.cc:(.text._ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv[_ZN6google8protobuf8internal29InternalMetadataWithArenaBaseINS0_15UnknownFieldSetENS1_25InternalMetadataWithArenaEE27mutable_unknown_fields_slowEv]+0x176): undefined reference to `google::protobuf::internal::ArenaImpl::AllocateAlignedAndAddCleanup(unsigned long, void (*)(void*))'
/tmp/ccfmvBXP.o:(.rodata._ZTVN13robotjoystick6ButtonE[_ZTVN13robotjoystick6ButtonE]+0xb8): undefined reference to `google::protobuf::Message::SpaceUsedLong() const'
collect2: error: ld returned 1 exit status

这是我用来编译代码的脚本:

#!/bin/sh
echo "Compiling dumbprotos.cpp"
echo ""
g++ dumbprotos.cpp proto_classes/Button.pb.cc -o ./pleasework -std=c++11 -lSDL2 -lprotobuf

我想这就是我需要向你们展示的一切。我错过了什么吗?我需要做什么才能编译我的 *.cpp 代码?

我在 Ubuntu 16.04 上。

4

1 回答 1

1

在考虑了@goduk 提供的评论后,我认为我应该进一步研究链接库问题并找到我需要获取的文件。事实证明,我没有链接到任何特定位置。我决定查看下面的文档protobuf-3.7.1/src/README.md以进一步探索以找到.../lib/目录。在重新阅读这些文档后,一个特定的部分引起了我的注意。

To compile a package that uses Protocol Buffers, you need to pass
various flags to your compiler and linker.  As of version 2.2.0,
Protocol Buffers integrates with pkg-config to manage this.  If you
have pkg-config installed, then you can invoke it to get a list of
flags like so:

    pkg-config --cflags protobuf         # print compiler flags
    pkg-config --libs protobuf           # print linker flags
    pkg-config --cflags --libs protobuf  # print both

For example:

    c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`

在我的笔记本电脑上,命令pkg-config --cflags --libs protobuf返回-pthread -I/usr/local/include -L/usr/local/lib -lprotobuf -pthread. 而不是试图确定正确的编译标志,我只需要在pkg-config --cflags --libs protobuf最后调用所需的标志。我以前从未听说过 pkg-config,但这解决了我所有的问题。最后的 bash 脚本行现在是这样的:

g++ dumbprotos.cpp proto_classes/Button.pb.cc -o ./pleasework -std=c++11 -lSDL2 `pkg-config --cflags --libs protobuf`

谢谢您的帮助。(这一个链接器类型问题。)

我还应该提到,如果 protobuf 对象包含其他 protobuf 对象,则必须在命令行调用中包含这些对象:

g++ my_program.cc my_proto_imported.pb.cc my_proto_containing.pb.cc `pkg-config --cflags --libs protobuf`

这意味着这my_proto_imported.pb.cc是一个导入并在my_proto_contained.pb.cc.

于 2019-06-02T02:59:55.487 回答