c# - 从 C# 调用 C++ 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);

我收到 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);

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

最佳答案

 _In_opt_  DWORD  UsernmaeLength

SAL 注释不是很有用。它可能试图告诉您的是,您可以为字符串缓冲区参数传递 NULL。在这种情况下,您传递的缓冲区长度无关紧要。它实际上不是 [可选],如果您真的不想返回字符串,您可以考虑简单地传递 0。

第三个参数不能是 String 或 out,因为它是一个不可变类型,并且该函数想要写入您传递的缓冲区。它必须是 StringBuilder。第二个参数必须是它的容量。请务必使 StringBuilder 足够大以适合用户名。如果不是,那么会发生什么不是很明显,希望函数然后只返回错误代码而不是静默截断字符串。测试一下。

第一个参数是通过引用传递的 bool,[Out] out bool。它不太可能是 SetLastError,它只能由 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);

如果您仍然遇到问题,那么如果您无法自行调试,则需要此代码作者的帮助。提供一个小的重现,这样他就可以轻松地重现问题。

关于c# - 从 C# 调用 C++ dll 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48922166/

相关文章:

c# - 使现有的 C# Windows 应用程序在 linux 上运行

c++ - 是否存在针对 C/C++ 的 R 编译器?

c++ - 如何重现浮点 cos(x)!=cos(x)

c# - System.Int32[] 显示而不是数组元素

c# - 有没有办法显示向上滑动面板,当用户向上滑动时显示更多数据?

c# - 当我在组合框中选择一个项目时如何防止 TextChanged 事件?

c++ - 如何获得正在运行的进程的启动时间?

c++ - FFMPEG I/O 的自定义读取功能

c++ - Qt 5 应用程序的平面目录部署?

c# - 把 $(SolutionDir)\packages\in .csproj 文件而不是 ..\packages\