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# 中执行此操作。
最佳答案
您必须删除 out
关键字来自 StringBuilder
参数。平原StringBuilder
参数被编码为指向字符数组的指针。如果您希望 native 代码接收 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
并且您需要确保空终止符的长度约定正确。我无法判断您的函数是否返回包含空终止符的长度。
正如 @Ben 指出的,您的注释与文本描述不匹配。
/* [ in ] */ WCHAR * const pwszFilterPath
[ in ] 应该暗示数据正在流入函数。如果是这样,类型应该是 const WCHAR*
。但事实并非如此。这是一个输出参数。所以代码应该是:
/* [ out ] */ WCHAR * const pwszFilterPath
关于c# - 如何将 C 函数签名转换为 C# 并在 native DLL 中调用该函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20600061/