爬坑经历:C#调用C++的DLL遇到的问题(LoadLibrary)

事情经过:.net core和.net framework两个项目一直用的LoadLibraryA这个方法来加载Dll的,然后莫名其妙的有用户反馈功能异常。

之前的写法:
使用LoadLibraryA
改后的写法:
使用LoadLibrary

个人总结:本人之前对宽字符和多字符的概念,以及LoadLibrary,LoadLibraryA,LoadLibraryW 不是很清楚,导致调用的代码写的有误。

知识总结:

  1. LoadLibrary 和 LoadLibraryA 实际上是同一个函数,只是在 ANSI(LoadLibraryA)和 Unicode(LoadLibraryW)版本之间的一个别名。Windows 根据你的宏定义自动选择使用哪一个。

  2. 默认情况下,Windows 的字符编码是 Unicode,因此 LoadLibrary 默认是调用 LoadLibraryW,即宽字符版本。

  3. 如果你的 DLL 路径名仅包含 ASCII 字符,你可以安全地使用 LoadLibraryA。否则,你应该使用 LoadLibrary,它将根据你的宏定义转到正确的函数。

如果你确实需要调用这些 API,可以在 C# 中这样使用:

using System.Runtime.InteropServices;

public class Win32Native {
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr LoadLibrary(string libname);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool FreeLibrary(IntPtr hModule);
}

在这个例子中,CharSet = CharSet.Auto 指示运行时自动选择使用 LoadLibraryA 或 LoadLibraryW。

4.在.NET Core和.NET Framework中,字符串默认使用Unicode编码。字符串类型(string)的每个字符默认使用16位(2字节)的Unicode字符编码。所以我们可以说默认情况下是宽字符编码方式。

这个行为与创建的项目类型(例如WPF,ASP.NET,控制台应用程序等)无关,这是C#语言和.NET运行时的特性。它并不使用C++中的宽字符和多字节字符的概念。

5…在.NET Core或.NET Framework中,如果你需要加载并使用C++的DLL文件,你会需要使用到P/Invoke(Platform Invocation Services)来调用非托管代码。对于LoadLibrary函数,你可以按照以下方式来使用:

using System.Runtime.InteropServices;

public class Win32Native {
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr LoadLibrary(string libname);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool FreeLibrary(IntPtr hModule);
}

这里,DllImport是.NET用来声明将要调用的非托管DLL的方法。CharSet = CharSet.Unicode告诉运行时你期望的是Unicode版本的函数(即LoadLibraryW),这是因为.NET默认使用Unicode字符编码。

因此,在.NET环境中,你应该直接使用LoadLibrary,并且设定CharSet = CharSet.Unicode,而不是使用LoadLibraryA或LoadLibraryW。

6.宽字符编码和多字节编码是字符编码的两种类型,主要在处理字符时使用。这两种编码方法主要用于处理多语言环境,因为不同的语言可能需要不同数量的字节来表示一个字符。
宽字符编码:宽字符编码是一种固定长度的字符编码方案。在这种方案中,每个字符都使用相同数量的字节表示。例如,UTF-16和UTF-32是宽字符编码,其中每个字符分别使用2字节和4字节。这种编码方案的优点是易于处理和解析,因为每个字符的长度都是固定的。但是,这也可能导致空间浪费,因为一些字符可能并不需要那么多的字节就能表示。多字节编码:多字节编码是一种变长的字符编码方案。在这种方案中,字符可以由一个或多个字节表示。例如,UTF-8就是一种多字节编码,其中一个字符可以由1到4个字节表示。这种编码方案的优点是空间效率,因为它可以使用最小的必要字节数来表示一个字符。然而,处理和解析这种编码的字符可能会更复杂,因为每个字符的长度是变化的。在多语言编程环境中,UTF-8编码通常是首选的编码方案,因为它兼容ASCII,并且能够有效地处理各种语言的字符。

文章如有不对,欢迎大神指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柚米汇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值