从本机库读取流到 C#

问题描述

我有以下本机 C++ 函数:

// Decode binary format from file 'filename' into stream 'output'
bool read_private_format(const char * filename,std::ostringstream & output);

阅读上一篇关于 StringBuilderdelegate 的 SO 文章,我创建了一个中间 C 函数以暴露给 C# 层:

extern "C" {
  typedef char *(*StringBuilderCallback)(int len);
  __attribute__ ((visibility ("default")))
  bool c_read_private_format(const char * filename,StringBuilderCallback ensureCapacity,char *out,int len) {
    std::ostringstream oss;
    if( read_private_format(filename,oss) ) {
      const std::string str = oss.str();
      if( str.size() > len )
        out = ensureCapacity(str.size());
      strcpy(out,str.c_str());
      return true;
    }
    return false;
  }
}

在 C# 方面:

private delegate System.Text.StringBuilder StringBuilderEnsureCapacity(int capacity);
[System.Runtime.InteropServices.DllImport(NativeLibraryName,EntryPoint="c_read_private_format")]
private static extern bool c_read_private_format(string filename,System.IntPtr aCallback,System.Text.StringBuilder data,int size);

private static System.Text.StringBuilder callback(int capacity)
{
    buffer.EnsureCapacity( capacity );
    return buffer;
}

public static string readIntoString(string filename) {
  StringBuilderEnsureCapacity del = new StringBuilderEnsureCapacity(callback);
  System.IntPtr ptr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(del)
  if( c_read_private_format( ptr,buffer,buffer.Capacity ) ) {
    string str = buffer.ToString();
    return str;
  }
  return null;
}

由于某种原因,这没有按预期工作,当打印 char* 返回的 callback 的地址时,它的行为就像返回的指针是调用 {{1} 之前的指针一样} (我可以通过第二次调用来验证,在这种情况下,C层中的EnsureCapacity是不同的)。

我的问题是:

  • 如何在 .NET SDK (5.0.202) 中有效地从 C 中检索 UTF-8 字符串?

我事先不知道字符串有多长。从技术上讲,我可以高估 StringBuilder 容量,以便我可以在我的文件中重复使用,但感觉好像有更好的方法可以将不断增长的流传递到 c 层。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)