主程序和动态库交互注意事项

1,dll 库接口参数 char * 好还是 void * 好
标准 C 约定:很多 C/C++ 库的接口习惯于使用 char* 来传递字符串或字节流,因此这种约定俗成的做法更易于理解和使用。
char* 直接表明了你在处理字符数据或字符串。如果接口的目的是传递字符串或字符数组,使用 char* 是直观且合适的。
函数需要传递未知或多种类型的数据,参数可能是非字符串的内存块或复杂的数据结构,这种情况可能更适合用 void *

2,如果是传 char * 需要分配堆内存吗
如果传递的是静态字符串或全局变量,不需要分配堆内存。
如果字符串的生命周期需要超过局部作用域,或者在不同函数间传递,通常需要动态分配(堆)内存。

3,需要const char * 吗
安全性:传递静态字符串或全局常量时,const char* 避免了对不可修改内存区域的写操作。
表达意图:调用者明确知道该函数不会修改传入的字符串,增加代码的可读性和自文档化。
兼容性:const char* 可以接受常量字符串(如字面量字符串),而 char* 不能

4,外面主程序申请的堆内存是否可以在dll里释放
在跨 DLL 边界使用内存管理时,需要非常小心。尤其是在一个模块(如 DLL 的外部)申请堆内存,然后在另一个模块(如 DLL 内部)释放内存,可能会导致一些问题。是否能够安全地这样操作,取决于几个因素:
(1)C 运行时库(CRT)的版本
不同的模块(例如应用程序和 DLL)可能使用不同版本的 C 运行时库(CRT)。每个运行时库都会维护自己的堆空间,如果在一个 CRT 中分配的内存尝试在另一个 CRT 中释放,会导致未定义行为,包括内存泄漏、崩溃等。
(2)静态链接 vs 动态链接
静态链接 CRT:如果应用程序和 DLL 都静态链接各自的 CRT 库(例如通过 libcmt.lib),它们将使用不同的堆。如果在应用程序中分配内存并在 DLL 中释放,问题更容易发生,因为它们实际上是使用了不同的堆管理系统。
动态链接 CRT:如果应用程序和 DLL 都链接到相同的动态 CRT 库(如 MSVCRT.dll),那么它们将共享相同的堆管理器。此时可以安全地跨模块进行内存分配和释放操作。
要确保这种情况下的安全性,你需要确保应用程序和所有使用的 DLL 使用相同的动态链接 CRT。可以通过项目设置确保这一点,例如在 Visual Studio 中,选择 动态链接 CRT(/MD 或 /MDd,分别用于 Release 和 Debug 模式)。
推荐的解决方案:
内存的分配与释放在同一模块进行:
确保主程序和所有 DLL 使用相同的动态链接 CRT
自定义内存管理接口:
你可以在 DLL 中提供自定义的内存管理接口,让外部程序通过这些接口进行分配和释放。例如,你可以提供 allocate 和 free 函数,这样外部调用者无需直接处理堆内存释放,避免了跨模块的内存管理。
// DLL 提供内存分配和释放接口
__declspec(dllexport) void* my_malloc(size_t size) {
    return malloc(size);
}

__declspec(dllexport) void my_free(void* ptr) {
    free(ptr);
}
跨模块内存管理问题总结:
避免跨模块分配和释放内存,除非你能确保所有模块使用相同的动态链接 CRT。
推荐的做法是提供接口,让内存的分配和释放都在同一模块中完成。
确保所有模块都使用动态链接的 CRT,如果你需要在不同模块之间分配和释放内存。

5,主程序使用动态的CRT, dll使用静态的会有问题吗
如果主程序使用动态链接的 CRT(/MD),而 DLL 使用静态链接的 CRT(/MT),可能会导致问题,尤其是在内存分配和释放以及其他 C 运行时库相关操作上。这是因为主程序和 DLL 将使用不同的堆管理器,它们不能安全地在不同模块之间共享内存或其他资源。

6,CRT 是指什么
CRT 指的是 C Runtime Library(C 运行时库),它是用于支持 C/C++ 程序运行的基础库,提供了许多基本功能,比如内存管理(malloc/free)、输入输出(printf/scanf)、文件操作、数学运算等。

7,unity 编译的工程怎么设置这些CRT状态
在 Unity 项目中,通常不需要手动设置 CRT(C Runtime Library)的链接方式,因为 Unity 的编译和构建流程会自动处理这些底层细节。Unity 使用的是 Mono 或 IL2CPP(Intermediate Language To C++)来编译 C# 代码,并会通过相应的工具链生成最终的二进制文件。
Unity 项目本身:你无法直接控制 Unity 使用的 CRT,因为 Unity 使用的是 Mono 或 IL2CPP。IL2CPP 会自动处理相关的编译和链接设置。
C++ 原生插件:如果你编写了 C++ 插件并需要在 Unity 中使用,建议在 Visual Studio 中设置为 动态链接的 CRT(/MD),以确保与 Unity 的内存管理系统兼容。

8,选择 MD是会生成 .exp 文件
生成条件:.exp 文件通常在 动态链接的 CRT(/MD) 的项目中生成,因为这涉及到生成和链接动态库(DLL),而不是静态链接库。
用途:.exp 文件包含有关 DLL 导出的符号的信息,它是生成 .lib 文件的中间产物。.lib 文件用于链接到 DLL,以便其他程序可以调用 DLL 中的导出函数。
通常情况下,.exp 文件不需要提供给最终用户或发布版本的用户。 .exp 文件主要是用于编译和链接过程中,特别是涉及到 DLL 的构建和链接。

9, MSVCRT.dll 和 vcruntime140.dll,msvcp140.dll
(1)MSVCRT.dll
全称:Microsoft Visual C++ Runtime Library
版本:这是一个较老的 C 运行时库,来自 Visual Studio 6.0 和早期版本的 Visual Studio。
用途:提供 C 语言的标准库函数(如 printf、malloc 等),用于早期的 Visual C++ 应用程序。
位置:通常位于 C:\Windows\System32。
兼容性:适用于使用早期版本的 Visual Studio 编译的程序。现代应用程序一般不会直接依赖 MSVCRT.dll,而是使用更新的运行时库。
(2)vcruntime140.dll
全称:Visual C++ Runtime Library (Version 14.x)
版本:这是 Visual Studio 2015、2017 和 2019 中的 C++ 运行时库。
用途:提供 C++ 标准库函数和其他 C++ 特性,例如异常处理、RTTI(运行时类型识别)等。
位置:通常位于 C:\Windows\System32 或 C:\Program Files (x86)\Microsoft Visual Studio\2019\VC\Redist\MSVC\<version>\vc_redist.x86.exe(安装时的路径)。
兼容性:用于使用 Visual Studio 2015、2017 或 2019 编译的程序。确保 DLL 版本与编译器版本匹配,以避免运行时错误。
(3)msvcp140.dll
全称:Microsoft C++ Standard Library (Version 14.x)
版本:与 vcruntime140.dll 对应,提供 C++ 标准库的实现(如 STL,标准模板库)。
用途:提供 C++ 标准库函数,如 std::vector、std::map 等。
位置:通常位于 C:\Windows\System32 或类似的 Redistributable 安装路径。
兼容性:也与 Visual Studio 2015、2017 或 2019 对应,确保版本匹配以避免运行时问题。
总结和使用建议
MSVCRT.dll:适用于较旧版本的 Visual Studio 编译的程序,现代应用程序更倾向于使用更新的运行时库。
vcruntime140.dll 和 msvcp140.dll:适用于 Visual Studio 2015、2017 和 2019 编译的程序,这些库提供了现代 C++ 标准库的支持。通常需要将这些库与 Visual Studio Redistributable 一起分发,确保目标系统上安装了正确的运行时库。

10, MSVCRT.dll:适用于较旧版本的 Visual Studio 编译的程序,现代应用程序更倾向于使用更新的运行时库。 现在更新的库叫什么?
对于现代 C++ 应用程序,更新的 C 运行时库是 vcruntime140.dll 和 msvcp140.dll,它们是 Visual Studio 2015、2017 和 2019 版本中的运行时库的一部分。以下是一些更新版本的运行时库以及它们的名称和用途:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值