DLL相关问题

1.cmake生成动态库

# Linux生成so,Windows生成dll
# SHARED ->生成动态库
# STATIC ->生成静态库
add_library(${PROJECT_NAME} SHARED ${ALL_SRCS})

2.动态库生成后,复制到程序执行目录里。

可以放在主程序或动态库的cmake里,生成时把dll复制到exe的目录里。

set(DLL_NAME module)
add_custom_command(
    TARGET ${PROJECT_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
        $<TARGET_FILE_DIR:${DLL_NAME}>/$<TARGET_FILE_NAME:${DLL_NAME}>
        $<TARGET_FILE_DIR:${PROJECT_NAME}>
)

3.dll使用方法分为两种。

动态库也是库,也要链接,分为:
Implicit Linking 隐式链接,静态加载dll。
Explicit Linking 显示链接,动态加载dll。

  • 隐式链接

    程序运行前就加载dll,dll里的函数就像静态库一样使用。 cmake里需要在主程序模块添加:

    link_directories(${CMAKE_BINARY_DIR}/module) 
    link_libraries(module)
    

    编译时,主程序要include动态库的头文件,动态库的目录里除了dll,还要有对应的lib。
    这个dll使用很方便,但如果exe找不到dll,就运行失败。

  • 显式链接

    程序在需要时才加载dll,不需要时可以卸载。找不到dll,也不会运行不起来,只是dll相关的功能不能用。
    cmake里什么都不需要。编译也不需要头文件,不需要lib。dll也只是运行时才需要。
    这种方式需要程序自己加载dll,查找dll提供的函数,调用这些函数,还要处理卸载dll等。

#include <Windows.h>
#include <iostream>
#include <string>
 
int main() {
    HINSTANCE hDll = LoadLibrary("module.dll");
    if (hDll == NULL)
    {
        std::cout << "load dll fail \n";
        return -1;
    }
    using FUNC_PRINT_ADDR = void(*)(std::string);
    FUNC_PRINT_ADDR print = (FUNC_PRINT_ADDR)GetProcAddress(hDll, "print");
    if (print == NULL)
    {
        std::cout << "load address fail \n";
        return -1;
    }
    print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    FreeLibrary(hDll);

    return 0;
}

4.dll与智能指针

一开始我在dll里导出一个返回智能指针的指针的函数,执行后,这个从dll里返回的智能指针就析构了。
后来我在dll里导出一个返回函数指针的函数,这个函数指针指向一个返回智能指针的函数,我先get第一个函数,执行得到返回智能指针的函数,执行得到返回的dll里的智能指针。
使用dll里来的智能指针,需要注意:卸载dll前,需要保证没有其他智能指针指向这个智能指针。 因为dll卸载,一定会回收dll里返回的智能指针指向的对象。回收后,我们主程序里如果还有智能指针指向那个对象,智能指针析构时就会crash。
可以通过调用智能指针的reset(), 解除引用。

5.同一个类,在exe和dll里,成员函数实现不一样。

在exe里把该类的一个对象的指针,传给一个dll里导入的函数,在该函数里,调用该类的成员函数会有什么结果?
会执行dll里类的成员函数,但用成员变量时exe里的传入的。
反过来,从dll里返回一个该类的对象指针,在exe里执行该类的成员函数,会执行exe里类的成员函数,成员变量是从dll里传入的。
成员变量是跟指针走的,成员函数是调用各自的实现。
所以尽量不要在两边分别实现同一个类。

6.一种不导出也能使用函数的方法

通过上面折腾,我发现,可以通过导出一个返回函数指针的函数,来返回一个dll里的函数,实现不导出函数也能使用函数。

7.观察导出类可以看到,导出的东西不包括private成员变量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值