设置 protobuf 项的值也会替换先前设置的变量

Setting a protobuf item's value replaces a previously set variable as well

我已经创建了一个简单的基于 Protobuf 的配置文件,并且一直使用到现在为止没有任何问题。问题是我在我的设置中添加了两个新项目 (Config.proto),现在我为最后一个变量设置的任何值都反映在前一个变量中。

以下快照更好地说明了这一点。如下所示,fv_shape_predictor_pathfv_eyenet_path 的值仅取决于设置的顺序。最后设置的一个更改其他值。

我确保重新构建了与 Config.proto 相关的 cpp 文件。我还在 Linux 下测试了这个,它工作得很好。它似乎只发生在 windows!它也不会影响相同设置中的任何其他项目。就这两个新的。

我不知道是什么原因造成的,也不知道该如何解决。作为参考,这是 protobuf 的样子:

syntax = "proto3";
package FVConfig;

message Config {

    FV Configuration = 4 ;
    
    message FAN_MODELS_WEIGHTS{
        string fan_2DFAN_4 =  1; 
        string fan_3DFAN_4 =  2; 
        string fan_depth   =  3; 
    }
    
    message S3FD_MODELS_WEIGHTS{
        string s3fd = 1; 
    }
  
    message DLIB_MODELS_WEIGHTS{
        string dlib_default = 1; 
    }
     
    message MTCNN_MODELS_WEIGHTS {
        string mt_onet = 1; 
        string mt_pnet = 2; 
        string mt_rnet = 3; 
    }

    message FV_MODEL_WEIGHTS {
        string r18 = 1; 
        string r50 = 2; 
        string r101 = 3;
        repeated ModelContainer new_models_weights = 4;

        message ModelContainer{
            string model_name = 1;
            string model_weight_path = 2;
            string description = 3;
        }
    }

    message FV {
        MTCNNDetectorSettings mtcnn = 1 ;
        FaceVerificationSettings fv = 2 ;
  }

    message MTCNNDetectorSettings {

        Settings settings = 1;
        MTCNN_MODELS_WEIGHTS model_weights = 4;
        
        message Settings {
            string mt_device            = 2;
            int32 mt_webcam_source      = 100;
            int32 mt_upper_threshold    = 600; 
            int32 mt_hop                = 700; 
        }
    }

    message FaceVerificationSettings {

        Settings settings = 1;
        FV_MODEL_WEIGHTS model_weights = 2;
        
        message Settings {
            string fv_model_name = 1; 
            
            string fv_model_checkpoint_path = 2; 
            bool fv_rebuild_cache   = 3;
            
            bool fv_short_circut    = 6;
            bool fv_accumulate_score = 7;
            
            string fv_config_file_path = 10;
            string fv_img_bank_folder_root = 11;
            string fv_cache_folder = 12;
            string fv_postfix       = 13;
            string fv_device        = 14;

            int32 fv_idle_interval = 15; 
            bool fv_show_dbg_info = 16;
            
            // these are the new ones
            string fv_shape_predictor_path = 17;
            string fv_eyenet_path = 18;
            }
    }

} //end of Config message

我在这里错过了什么?我该怎么办?重新启动 Windows 和 Visual Studio 也没有任何好处。我在 Linux 和 Windows.

上都使用了 protobuf 3.11.4

这个问题似乎只存在于 Protobuf 3.11.4 的 Windows 版本中(虽然没有测试任何较新的版本)。

基本上发生的事情是我首先创建一个 Config object 并使用一些默认值对其进行初始化。当我将这两个条目添加到我的 Config.proto 时,我忘记像其他条目一样添加一个初始化条目,认为我可以使用默认值(我假设是 "")。

这不会在 Linux/G++ 下造成任何问题,并且程序可以正常构建和运行并按预期工作。然而,在 Windows 下,这会导致您刚刚看到的行为,即设置任何新添加的条目,也会设置其他条目的值。所以基本上我要么必须创建一个全新的 Config object 要么必须在使用 load_default_config.

时明确设置它们的值

更具体地说,这是我用来在 Protobuf 配置中设置一些默认值的片段。

它们位于一个单独的 header 中,名为 Utility.h:

   inline FVConfig::Config load_default_config()
    {
        FVConfig::Config baseCfg;
        auto config = baseCfg.mutable_configuration();
        load_fv_default_settings(config->mutable_fv());
        load_mtcnn_default_settings(config->mutable_mtcnn());
        return baseCfg;
    }

    inline void load_fv_default_settings(FVConfig::Config_FaceVerificationSettings* fv)
    {
        fv->mutable_settings()->set_fv_config_file_path(fv::config_file_path);
        fv->mutable_settings()->set_fv_device(fv::device);
        fv->mutable_settings()->set_fv_rebuild_cache(fv::rebuild_cache);
        ...

        // these two lines were missing previously and to my surprise, this was indeed
        // the cause of the weird behavior.  
        fv->mutable_settings()->set_fv_shape_predictor_path(fv::shape_predictor_path);
        fv->mutable_settings()->set_fv_eyenet_path(fv::eyenet_path);

        auto new_model_list = fv->mutable_model_weights()->mutable_new_models_weights()->Add();
        new_model_list->set_model_name("r18");
        new_model_list->set_description("default");
        new_model_list->set_model_weight_path(fv::model_weights_r18);
    }

    inline void load_mtcnn_default_settings(FVConfig::Config_MTCNNDetectorSettings* mt)
    {
        mt->mutable_settings()->set_mt_device(mtcnn::device);
        mt->mutable_settings()->set_mt_hop(mtcnn::hop);
        ....
    }

不确定这是 Protobuf 中的错误,还是我这里的错误方法。