int __stdcall getProps( /* [ in ] */ void * context,
/* [ in ] */ const UINT32 index,
/* [ in ] */ WCHAR * const pwszFilterPath,
/* [ in, out ]*/ UINT32 * const pFilterPathSizeInCch,
/* [ in ]*/ WCHAR * const pwszFilterName,
/* [ in, out ] */ UINT32 * const pFilterNameSizeInCch );
这是签名在上面的C函数的正确C#签名:
[DllImport("myLib.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
public static extern int getProps( IntPtr context,
uint index,
[MarshalAs(UnmanagedType.LPWStr)]
out StringBuilder pwszFilterPath,
ref uint pFilterPathSizeInCch,
[MarshalAs(UnmanagedType.LPWStr)]
out StringBuilder pwszFilterName,
ref uint pFilterNameSizeInCch );
这里有问题,我不知道(我不知道C#)。有时当我让它工作时,我在StringBuilder变量中接收ANSI字符串,它们应该包含UNICODE字符。
想法是两次调用此函数。首先将pwszFilterPath和pwszFilterName设置为NULL,以便检索所需的大小,然后为这两个缓冲区分配内存,然后在第二次调用时检索值。我知道如何在C / C ++中完成它,而不是在C#中。
答案 0 :(得分:3)
您必须从out
参数中删除StringBuilder
关键字。普通的StringBuilder
参数被编组为指向字符数组的指针。如果您希望本机代码接收NULL
,请传递C#null
。
[DllImport("myLib.dll", CharSet = CharSet.Unicode)]
public static extern int getProps(
IntPtr context,
uint index,
StringBuilder pwszFilterPath,
ref uint pFilterPathSizeInCch,
StringBuilder pwszFilterName,
ref uint pFilterNameSizeInCch
);
通话模式如下:
null
传递给StringBuilder
参数以找出缓冲区大小。StringBuilder
个实例。StringBuilder
实例调用该函数。也许是这样:
uint filterPathLength = 0;
uint filterNameLength
int retval = getProps(
context,
index,
null,
ref filterPathLength,
null,
ref filterNameLength
);
// check retval
StringBuilder filterPath = new StringBuilder(filterPathLength);
StringBuilder filterName = new StringBuilder(filterNameLength);
int retval = getProps(
context,
index,
filterPath,
ref filterPathLength,
filterName,
ref filterNameLength
);
// check retval
并且您需要确保获得null终止符的长度约定。我无法判断你的函数是否返回包含null-terminator的长度。
正如@Ben指出的那样,您的注释与文字说明不符。
/* [ in ] */ WCHAR * const pwszFilterPath
[in]应该暗示数据正在流入函数。如果是这样,则类型应为const WCHAR*
。但事实并非如此。这是一个out参数。所以代码应该是:
/* [ out ] */ WCHAR * const pwszFilterPath