C++ protobuf中的路径

C++ protobuf中的路径,c++,protocol-buffers,C++,Protocol Buffers,我不太理解protobuf中的路径。我的文件布局如下: 顶 A a、 原型 B C c、 proto/导入“A/A.proto” 我已经基于protobuf编写了一个RPC系统,我需要从c.proto生成两种文件(客户机和服务器代码)。客户端代码应该放在B中,服务器代码仍然放在C中 我写不出正确的命令 Top>protoc-I=--client_out=./B/C/C.proto将在B/C中生成客户端代码,而#include在代码中的路径将错误 Top/C>protoc-I=..

我不太理解protobuf中的路径。我的文件布局如下:

    • A
      • a、 原型
    • B
    • C
      • c、 proto/
        导入“A/A.proto”
我已经基于protobuf编写了一个RPC系统,我需要从
c.proto
生成两种文件(客户机和服务器代码)。客户端代码应该放在B中,服务器代码仍然放在C中

我写不出正确的命令

Top>protoc-I=--client_out=./B/C/C.proto
将在
B/C
中生成客户端代码,而
#include
在代码中的路径将错误


Top/C>protoc-I=../-I=./-client\u out=.//C.proto
引导一个
protobuf\u AddDesc.*
错误。

对于每个
.proto
文件,
protoc
尝试确定文件的“规范名称”——一个区别于可能进入系统的任何其他
.proto
文件的名称。事实上,理想情况下,规范名称不同于世界上所有其他
.proto
文件。规范名称是从另一个
.proto
文件导入
.proto
文件时使用的名称。它还用于决定在何处输出生成的文件以及要生成的
#包括哪些内容

对于在命令行上指定的
.proto
文件,
protoc
通过尝试确定导入该文件时使用的名称来确定规范名称。因此,它通过导入路径(用
-I
指定)查找作为文件名前缀的路径。然后删除该前缀以确定规范名称

在本例中,如果指定
-I=。C/C.proto
,则规范名称为
C/C.proto
。如果指定了
-I=C C/C.proto
,则规范名称将仅为
C.proto

重要的是,任何试图导入
.proto
文件的文件都必须使用编译文件时确定的规范名称进行导入。否则,您将得到关于
AddDesc
的链接器错误

一般来说,如果指定某个目录作为源代码树的“根”,并且所有代码都位于该目录的子目录中,并且具有指定项目的唯一名称,那么一切都可以正常工作。“根”目录应该是传递给
-I
-client\u out
的目录。或者,源文件和生成的文件可以有单独的目录,但是生成的文件目录应该有一个镜像源目录的内部结构。然后,可以将生成的文件目录指定为<代码> -clitIOXOUT,并且当运行C++编译器时,在“包含路径”中指定源文件和生成文件目录。


如果您有一些其他设置—例如,
.proto
文件位于与
.pb.h
文件不同的规范路径—那么不幸的是,您在使
protoc
执行您想要的操作时会遇到一些问题。虽然,考虑到您正在编写一个自定义代码生成器,您可以根据其输出文件的组织方式发明任何规则,但偏离标准代码生成器遵循的规则可能会导致许多小陷阱。

include
行是什么样的?
include“C/C.pb.h”
,应该是
#包括“c.pb.h”
。它是由
printer->Print(#包括\“$basename$.pb.h\”、“basename”、StripProto(文件\->name())生成的为什么这是一个问题;当然,您只需要将正确的
-I
选项传递给编译器,以便它可以找到头文件?错误的
#include
位于
B/c.pb.cc
,它应该包含
B/c.pb.h
,而不是
c/c.pb.h
,我不知道-为什么路径层次结构如此复杂?你不能把
.proto
文件和生成的源文件放在同一个目录下吗?回答得很好。我不知道如何“禁用”包含输出文件的完整路径。