首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨CPP文件的外部对象(Boost Filesystem/Variants,Lib撰稿人)

跨CPP文件的外部对象(Boost Filesystem/Variants,Lib撰稿人)
EN

Stack Overflow用户
提问于 2022-09-30 00:46:55
回答 1查看 57关注 0票数 0

我给你们弄了个假的复杂的。

我正在尝试开发一个使用INI配置文件的程序(我使用的是library库),如下所示:

代码语言:javascript
复制
[General]
output_directory = /scratch/miles/trans_assembly_pipeline/

[SRA accessions]
SRR18328591
SRR28481881

它将其中的信息解析为映射,按节索引,然后按键进行索引,如下所示(唯一重要的位实际上是变量对象中的char*选项):

代码语言:javascript
复制
map<string, map<string, boost::variants<int, bool, double, string, char*>>

因为INI文件中的键可以有各种类型,所以我使用Boost的“变体”库来允许多个值类型。最后,为了方便文件管理,我使用Boost的“文件系统”库。

我有一个INI解析实现文件,它基本上只是将INI数据存储到这样定义的映射类型中(仅包含函数声明和定义指令的标题可以在底部找到):

代码语言:javascript
复制
#include "ini_parse.h"


namespace fs = boost::filesystem;

// Dispatch INI data to a map, indexable by sections, then by keys
static int ini_callback(IniDispatch * const dispatch, void * map_pt) {
  #define thismap (reinterpret_cast<INI_MAP*>(map_pt))
  if (dispatch->type == INI_COMMENT) {
    return 0;
  }
  if (dispatch->type == INI_SECTION) {
    INI_MAP_ENTRY newSec;
    thismap->insert(std::pair<std::string, INI_MAP_ENTRY>(dispatch->data, newSec));
    return 0;
  }
  if (dispatch->type == INI_KEY) {
    (*thismap)[dispatch->append_to].insert(std::pair<std::string, BOOST_VAR>(dispatch->data, dispatch->value));
  }
  return 0;
}


// Given a FILE object, return a buffer containing its contents
char * make_ini_buffer(FILE * iniFile) {
  char * iniBuffer;
  long sz; 
  fseek(iniFile, 0L, SEEK_END);
  sz = ftell(iniFile);
  rewind(iniFile);
  iniBuffer = (char*)malloc(sz + 1); 
  fread(iniBuffer, 1, sz, iniFile);
  return iniBuffer;
}


// Given the path/name of an INI config file, return a map of its data
// which can be indexed by sections, and then by keys
INI_MAP make_ini_map(const char * configPath) {
  FILE * configIni = fopen(configPath, "r");
  fs::path configPathObj(configPath);
  try {
    if (!configIni) {
      std::string fileError = "ERROR: Cannot open config file: ";
      throw std::runtime_error(fileError);
    }   
  } catch (std::runtime_error& e){ 
    std::cerr << e.what() << configPathObj.filename() << std::endl;
    return {}; 
  }
  INI_MAP iniMap;
  char * iniBuffer = make_ini_buffer(configIni);
  strip_ini_cache(iniBuffer, strlen(iniBuffer), INI_DEFAULT_FORMAT,
                  NULL, ini_callback, &iniMap);
  delete [] iniBuffer;
  return iniMap;
}


INI_MAP cfgIni = make_ini_map("../config.ini");

注意最后一行,在任何其他函数之外,定义'cfgIni‘。其想法是定义一个全局INI数据存储对象,它可以被其他文件外部使用--例如,如下所示:

代码语言:javascript
复制
#include "ini_parse.h"

int main() {
  extern INI_MAP cfgIni;
  extern int size_path;
  
  std::cout << cfgIni["General"]["output_directory"] << std::endl;

  return 0;
}

现在是我的问题:在这个单独的文件中对外声明'cfgIni‘时,从在实现文件中定义它的位置到在外部声明它并在这里捕获内存似乎正在丢失。我没有问题访问父/子映射中的键,但是这些值更具有虚幻性。

当打印"General“部分的内容时,返回"output_directory”,没有问题。

我希望上面代码片段中的最后一行会打印filepath *数组,在INI文件中将"output_directory“设置为该数组。

然而,我却得到了一些随机字符,比如"�U“。更令人困惑的是,当我在内存中输出这个返回值的大小时,它会返回'40',这是该文件路径中正确的字符数。

我已经链接了我使用的库的文档和它们的功能。对这个问题的长度/复杂性表示歉意。

strip_ini_cache(): https://madmurphy.github.io/libconfini/html/confini_8c.html#a25d648d387f6e8bc36e7965accfca63b

Boost.variant: https://www.boost.org/doc/libs/1_61_0/doc/html/variant.html

Boost.filesystem: https://www.boost.org/doc/libs/1_80_0/libs/filesystem/doc/reference.html

下面是我的头文件:

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <map>
#include <cstdio>

#include <confini.h>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>

#define BOOST_VAR boost::variant<int, bool, double, std::string, char*>
#define INI_MAP_ENTRY std::map<std::string, BOOST_VAR>
#define INI_MAP std::map<std::string, INI_MAP_ENTRY>



static int ini_callback(IniDispatch * const dispatch, void * map_pt);

char * make_ini_buffer(FILE * iniFile);

INI_MAP make_ini_map(const char * configPath);
EN

回答 1

Stack Overflow用户

发布于 2022-09-30 02:58:23

这一问题的答案实在是微不足道。当通过值传递时,就像我在其中一个文件中所做的那样,创建了对象的一个浅拷贝,其中指向char数组的指针被野生地址覆盖。

解决办法是通过康斯特参考。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73902919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档