从C#调用C++ dll方法

3

我正在尝试调用C++ dll中的方法。

HRESULT WINAPI TestMethod(
_Out_     BOOL   *isSuccess,
_In_opt_  DWORD  UsernmaeLength,
_Out_opt_ LPWSTR userName );

我编写的C#包装方法如下

        [DllImport("Test.dll", CharSet = CharSet.Unicode, SetLastError = true ,CallingConvention = CallingConvention.StdCall)]
    public static extern int TestMethod (
        IntPtr isSuccess,
        [In, Optional] int UsernmaeLength,
        out string userName
    );

我在程序中调用了这个方法

Wrapper. TestMethod (isSuccess, 200, out userName);

我遇到了System.AccessViolationException错误。

尝试更改C#包装器方法:

[DllImport("Test.dll", CharSet = CharSet.Unicode, SetLastError = true ,CallingConvention = CallingConvention.StdCall)]
    public static extern int TestMethod (
        bool isSuccess,
        [In, Optional] int UsernmaeLength,
        out string userName
    );
    //Caller
    bool isSuccess = false;
    Wrapper. TestMethod (isSuccess, 200, out userName);

请问您能否帮我理解我在这里做错了什么?


你应该尝试使用 uint UsernmaeLength - FaizanHussainRabbani
out IntPtr userName - FaizanHussainRabbani
我尝试了以上三种排列组合,但是没有成功! - saTech
尝试以下代码:public static extern int TestMethod ( [Out] ref bool isSuccess, [In, Optional] uint UsernmaeLength, [Out, Optional] IntPtr userName ); - FaizanHussainRabbani
"isSuccess"也是输出参数。 - FaizanHussainRabbani
显示剩余2条评论
1个回答

3
 _In_opt_  DWORD  UsernmaeLength

SAL注释并不是很有用。它可能想告诉你的是,你可以将空字符串缓冲区参数传递为NULL。在这种情况下,你传递的缓冲区长度并不重要。实际上它并不是可选的,如果你真的不想要一个字符串返回,可以考虑简单地传递0。
第三个参数不能是String或out类型,因为那是一个不可变类型,而函数想要写入你传递的缓冲区。它必须是StringBuilder类型。第二个参数必须是它的容量。确保StringBuilder足够大以容纳用户名。如果不是,则不太明显会发生什么,希望函数只是返回一个错误代码而不是默默地截断字符串。请进行测试。
第一个参数是通过引用传递的布尔值,[Out] out bool。不太可能设置LastError,那只有winapi函数才会这样做。它已经在HResult中嵌入了一个错误代码。小于0的值表示出现错误。Stdcall是默认值。总结一下:
[DllImport("Test.dll", CharSet = CharSet.Unicode)]
public static extern int TestMethod (
    [Out] out bool isSuccess,
    int userNameLength,
    StringBuilder userName
);

被称为:

bool success;
var name = new StringBuilder(666);
int hr = TestMethod(out success, name.Capacity, name);
if (hr < 0) Marshal.ThrowExceptionForHR(hr);

如果您仍然遇到问题,则需要本代码的作者帮助,如果您自己无法调试。请准备好一个小的复制品,以便他可以轻松地重现该问题。

你太棒了! :) 它起作用了,问题在于第三个参数。 - saTech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接