c# - pinvoke - 传递一个字符串 [] 作为输出参数

标签 c# c++ arrays pinvoke

我无法使下面的 p/invoke 代码正常工作,请帮忙,谢谢。

下面的顶点在 C++ 调用后保持为空。我尝试使用 IntPtr 而不是 string[],C++ 调用后 IntPtr 保持为 0。

C++代码

extern "C"  __declspec(dllexport)
float compute_similarity(char** vertices)
{       
  vertices = new char*[2];
  vertices[0] = new char[3];
  vertices[1] = new char[3];

  strcpy(vertices[0], "he");
  strcpy(vertices[1], "ha");

  return 1.01;
}

C#代码

[DllImport("demo.dll", EntryPoint = "compute_similarity", 
    CallingConvention =  CallingConvention.Cdecl,   CharSet = CharSet.Ansi)]
static extern float compute_similarity(out string[] vertices);  
//also tried 'static extern float compute_similarity(out IntPtr vertices);'  

public string Func()
{
  string[] vertices; //also tried 'IntPtr vertices'
  float sim = compute_similarity(out vertices); 
  //break point here vertices stays null(or 0 for IntPtr)
  return sim.ToString();
}

最佳答案

我不认为它可以通过这种方式正确完成,因为您无法指定 P/Invoke 在将其转换为托管字符串后必须使用 delete[] 调用释放内存。

但是,使用 BSTRSAFEARRAYMarshalAs 属性,您可能有战斗的机会。

extern "C"  __declspec(dllexport)
float compute_similarity(SAFEARRAY** vertices)
{
    SAFEARRAY *pArr = SafeArrayCreateVector(VT_BSTR, 0, 2);
    if(pArr != NULL)
    {
        LONG index = 0;
        BSTR bs = SysAllocString(L"he");
        SafeArrayPutElement(pArr, &index, bs);
        SysFreeString(bs);
        index = 1;
        bs = SysAllocString(L"ha");
        SafeArrayPutElement(pArr, &index, bs);
        SysFreeString(bs);
    }
    *vertices = pArr;
    return 1.01;
}
[DllImport("demo.dll", EntryPoint = "compute_similarity", CallingConvention =  CallingConvention.Cdecl)]
static extern float compute_similarity(
    [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_BSTR)] out string[] vertices
);  

您仍然可以使用 IntPtr(并在 C# 端手动进行编码(marshal)处理,同时导出 delete_strings 函数),但请记住,您的函数必须采用其 char** 引用,否则不能实际修改它。

关于c# - pinvoke - 传递一个字符串 [] 作为输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19273828/

相关文章:

arrays - 从哈希数组计算平均时间

javascript - 如何将附加参数传递给排序函数

c# - asp.net 如何从html表中插入数据到数据库中

原始内存流上的 C# 数学性能

C++ fstream 变量

c++ - 连续碰撞检测——如何在 C++ 中根据这两个方程找到碰撞

c# - 按代码创建发票

c# - 如何让 AutoMapper 处理自定义命名约定?

c++ - 为什么按值返回对于非内置类型应该是 const 而对于内置类型不是 const?

c - 为什么 main 中的矩阵会改变?