如何C函数签名转换成C#和调用在本机DLL该功能? [英] How to convert C function signature to C# and call that function in the native DLL?

查看:147
本文介绍了如何C函数签名转换成C#和调用在本机DLL该功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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#签名:

Is this correct C# signature for a C function whose signature is above:

[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字符。

There is something wrong here and I do not know what (I do not know C#). Sometimes when I get it to work, I receive ANSI strings inside StringBuilder variables and they should contain UNICODE characters.

我们的想法是两次调用这个函数。首先用pwszFilterPath和pwszFilterName设置为NULL,以便检索所需要的尺寸,然后分配内存这两个缓冲区,然后检索第二呼叫的值。我知道该怎么做,在C / C ++,但不是在C#。

The idea is to call this function twice. First with pwszFilterPath and pwszFilterName set to NULL, in order to retrieve the required size, then allocate memory for these two buffers and then retrieve the values on the second call. I know how to do it in C/C++, but not in C#.

推荐答案

您必须删除退出的StringBuilder 参数关键字。一个普通的的StringBuilder 参数被编组为一个指向字符数组。如果你想在本机代码来接收 NULL ,通过C#

You must remove the out keyword from StringBuilder parameters. A plain StringBuilder parameter is marshalled as a pointer to character array. If you want the native code to receive NULL, pass 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
);



调用模式如下:

The call pattern is as follows:


  1. 的StringBuilder 参数,找出缓冲区的大小。
  2. 使用接收能力的构造函数重载
  3. 分配的StringBuilder 实例。

  4. 调用函数再次通过的StringBuilder 实例

  1. Pass null to the StringBuilder parameters to find out the buffer size.
  2. Allocate StringBuilder instances using the constructor overload that receives the capacity.
  3. Call the function again passing the StringBuilder instances.

也许是这样的:

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

和你需要确保你得到的长度公约正确的空终止符。我不能告诉你的函数是否返回长度,包括空终止。

And you'll need to make sure you get the length convention right for null-terminator. I cannot tell whether or not your function returns lengths that include the null-terminator.

由于@Ben指出的那样,你的注释不匹配的文字说明。

As @Ben points out, your annotations don't match the text description.

/* [ in ] */ WCHAR * const pwszFilterPath



[输入]应该意味着该数据流进的功能。如果是这样,类型应该是常量WCHAR * 。但它并非如此。这是一个OUT参数。因此,代码应为:

The [ in ] should imply that the data is flowing into the function. When that is so, the type should be const WCHAR*. But it's not the case. This is an out parameter. So the code should read:

/* [ out ] */ WCHAR * const pwszFilterPath

这篇关于如何C函数签名转换成C#和调用在本机DLL该功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆