1

如何将 C 中的char**基于数组转换为 C# 中的等效类型?

我有一个 DLL,它有一个函数,它接受一个char**缓冲区并用正确的数据填充它。

我在 C# 应用程序中使用这个 DLLDllImport

当我需要为此类功能指定return typeor时,问题就开始了。argument type

C# 中的哪种类型等价于 Cchar**数组?

我应该编组什么以及如何编组?

更新
这是我的 C 函数,它位于我的 dll 中:

CDLL_API wchar_t** GetResults(wchar_t* word, int* length, int threshold = 9);

这两个函数调用以下函数来获取它们的值:

wchar_t** xGramManipulator::CGetNextWordsList(const wchar_t* currentWord, int threshold)
{
    wstring str(currentWord);
    auto result = GetNextWordsList(str, threshold);

    return GetCConvertedString(result);
}

wchar_t ** xGramManipulator::GetCConvertedString(vector< wstring> const &input)
{
    DisposeBuffers();//deallocates the previously allocated cStringArrayBuffer.
    cStringArraybuffer = new wchar_t*[input.size()];
    for (int i = 0; i < input.size(); i++)
    {
        cStringArraybuffer[i] = new wchar_t[input[i].size()+1];
        wcscpy_s(cStringArraybuffer[i], input[i].size() + 1, input[i].c_str());
        cStringArraySize++;
    }
    return cStringArraybuffer;
}

我使用 wchar_T** 但我认为 C# 方面不应该有任何区别(因为 c# 默认支持 unicode!所以如果它不同,请也解决这个问题)

4

1 回答 1

3

在评论中,您声明您最感兴趣的是处理此功能:

CDLL_API wchar_t** GetResults(wchar_t* word, int threshold);

您不能指望 p/invoke 编组器为您编组返回值。你需要手动完成。更重要的是,您不能像当前设计的那样可靠地调用该函数。那是因为调用者无法获取返回数组的长度。您需要添加一个额外的参数以将数组长度返回给调用者:

CDLL_API wchar_t** GetResults(wchar_t* word, int threshold, int* len);

在 C# 方面,您可以这样声明:

[DllImport(@"DllName.dll", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr GetResults(
    [MarshalAs(UnmanagedType.LPWStr)]
    string word,
    int threshold,
    out int len
);

并且您需要确保您在您DllImport的本地代码中指定的调用约定匹配。我假设cdecl,但只有你知道。

像这样称呼它:

int len;
IntPtr results = GetResults(word, threshold, out len);
IntPtr[] ptrs = new IntPtr[len];
Marshal.Copy(results, ptrs, 0, len);
for (int i=0; i<len; i++)
{
    string item = Marshal.PtrToStringUni(ptrs[i]);
}

为避免内存泄漏,您需要导出另一个函数来释放由GetResults. 一旦你完成调用就调用它PtrToStringUni

坦率地说,这看起来非常适合混合模式 C++/CLI 解决方案。

于 2013-07-29T14:57:21.127 回答