C# 如何将基于字符的数组从基于C的dll转换为等效的C?

C# 如何将基于字符的数组从基于C的dll转换为等效的C?,c#,c,pinvoke,C#,C,Pinvoke,如何将C中基于char**的数组转换为C#中的等效类型 我有一个DLL,它有一个函数,它接受一个char**缓冲区并用正确的数据填充它 我使用DllImport 当我需要为此类函数指定返回类型或参数类型时,问题就开始了 C#中的哪种类型与Cchar**array等价 我应该做什么,怎么做 更新: 这是我的C函数,它位于我的dll中: CDLL_API wchar_t** GetResults(wchar_t* word, int* length, int threshold = 9); 这两个

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

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

我使用
DllImport

当我需要为此类函数指定
返回类型
参数类型
时,问题就开始了

C#中的哪种类型与C
char**
array等价

我应该做什么,怎么做

更新
这是我的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\u t**xGrammaManipulator::CGetNextWordsList(常量wchar\u t*currentWord,int阈值)
{
wstring-str(currentWord);
自动结果=GetNextWordsList(str,阈值);
返回GetCConvertedString(结果);
}
wchar\u t**xgrammaniperator::GetCConvertedString(向量常量和输入)
{
DisposeBuffers();//解除分配以前分配的CStringArrayBuffers。
cStringArraybuffer=new wchar_t*[input.size()];
对于(int i=0;i

我使用了wchar\u T**但我认为C端不应该有任何区别(因为C端默认支持unicode!因此,如果它不同,请也解决这个问题)

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

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
);
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]);
}
您需要确保在
DllImport
中指定的调用约定与本机代码的调用约定相匹配。我假设是cdecl,但只有你能确定

可以这样称呼:

[DllImport(@"DllName.dll", CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr GetResults(
    [MarshalAs(UnmanagedType.LPWStr)]
    string word,
    int threshold,
    out int len
);
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]);
}
int-len;
IntPtr results=GetResults(字、阈值、out len);
IntPtr[]ptrs=新的IntPtr[len];
封送处理副本(结果、PTR、0、len);

对于(int i=0;i您是否尝试使用ref string?
string[]
应该可以用,不知道我对此一无所知。那么wchar\u t**也适用于它吗?GetResults函数不包含关于分配数组大小的信息。谢谢,我会尝试一下,如果遇到任何问题,我会发表评论。再次感谢您所做的一切:)@Hossein是的,我真傻,应该是
IntPtr[]ptrs
,根据最新更新,您将参数转录到了
封送处理。复制
的顺序错误。