【问题标题】:Conversion of const char** to std::vector<std::string>const char** 到 std::vector<std::string> 的转换
【发布时间】:2014-06-11 11:22:30
【问题描述】:

我有以下包装器将我的 C++ 代码公开给 C#

extern "C" {
   LIBRARY_API void GenerateTables(
      const char* version, 
      const char* baseDir, 
      const char** fileList);
} // end extern "C"

void GenerateTables(
   const char* version,
   const char* baseDir,
   const char** fileList)
{
   std::string strVersion(version);
   std::string strBaseDir(baseDir);

   // I now need to convert my const char** to std::vector<std::string> 
   // so it can be passed to another internal method.
}

如何将我的const char** fileList 转换为std:vector&lt;std::string&gt;。我对 C++ 比较陌生,这里的内存分配有一个明显的问题。我可以做类似的事情

std::vector<std::string> vec;
for (int i = 0; i < fileList.length() /* length() of what!? */; i++)
    vec.push_back(/* what!? */);

如何进行所需的转换,是否有更好的方法通过互操作将字符串数组 (string[]) 从 C# 传递到 C++?

感谢您的宝贵时间。

【问题讨论】:

  • 我们是否应该假设列表由 NULL 指针终止?
  • 需要一些协议来确定数组的长度。这是什么?
  • 我希望得到fileList 变量中的字符串数。因此,在将数组传递给互操作方法之前,先使用 C# List&lt;string&gt; fileList = new List&lt;string&gt; { /* some list */ }; 然后使用 ToArray()。就像我说的,我以前没有这样做过,所以对其他方法持开放态度(如果有的话)。可以使用目录获取fileList,因为它们都包含在一个文件夹中,所以我可以传入另一个const char*,它包含一个目录路径,该目录路径又用于获取所需的文件路径?跨度>
  • 数组的长度可以变化。但是函数需要知道那个长度。如果没有,它如何遍历数组?如果从 C# 进行互操作,最简单的方法是将长度作为额外参数传递。

标签: c# c++ interop type-conversion


【解决方案1】:

您需要为非托管代码提供某种方式来获取长度。常用的方法有两种:

  1. 将数组的长度作为额外参数传递。
  2. 使用以空结尾的数组。当您遇到一个为空的项目时,该数组结束。

任何一个选项都很简单,您可以实施。选择完全取决于您的个人喜好。

如果您选择第一个选项,那么您可以像这样填充向量:

std::vector<std::string> files(fileList, fileList + length);

如果您选择第二个选项,那么您将使用这样的循环:

std::vector<std::string> files;
const char** filePtr = fileList;
while (*filePtr != nullptr)
    files.push_back(*filePtr++); 

【讨论】:

  • 非常感谢您的帮助,非常感谢。
【解决方案2】:

您需要知道fileList 数组的长度。一旦你知道它,你可以转换 fileList 使用

size_t length = ... ;
std::vector<std::string> files( fileList, fileList + length );

【讨论】: