C# 如何将基于字符的数组从基于C的dll转换为等效的C?
如何将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); 这两个
char**
的数组转换为C#中的等效类型
我有一个DLL,它有一个函数,它接受一个char**
缓冲区并用正确的数据填充它
我使用DllImport
当我需要为此类函数指定返回类型
或参数类型
时,问题就开始了
C#中的哪种类型与Cchar**
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
,根据最新更新,您将参数转录到了封送处理。复制
的顺序错误。