从C#调用C DLL方法

  • 本文关键字:DLL 方法 调用 c# c++
  • 更新时间 :
  • 英文 :


我试图调用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);

我正在获得系统。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);

您能帮我了解我在这里做错了什么吗?

 _In_opt_  DWORD  UsernmaeLength

SAL注释不是很有用。它可能试图告诉您的是,您可以通过null进行字符串缓冲区参数。在这种情况下,您要通过的缓冲长度通过的内容并不重要。它实际上不是[可选],如果您真的不想要字符串,则只需考虑通过0。

第三个参数不能是字符串或外出,因为这是不变的类型,并且该功能希望写入您通过的缓冲区。它必须是弦乐器。第二个论点必须是其能力。确保使StringBuilder足够大以适合用户名。如果不是这样,那就不是很明显了,希望该功能只需返回错误代码,而不是默默地截断字符串。测试。

第一个参数是通过引用[OUT] BOOL传递的BOOL。它不太可能仅由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);

如果您仍然遇到麻烦,则如果您无法自己调试,则需要该代码的作者的帮助。有一个少量的repro可用,以便他可以轻松地复制问题。

最新更新