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
    评论
Delphi是一种编程语言,而DLL(Dynamic-Link Library)是一种模块化的文件格式,用于存储代码和数据,可以被多个应用程序共享。DLL注入是一种技术,它允许将DLL文件加载到正在运行的进程中,并使得该进程能够调用DLL中的函数和使用其中的数据。 在Delphi中实现DLL注入的方法有很多种。一种常见的方法是使用Windows API函数LoadLibrary和GetProcAddress。通过调用LoadLibrary函数,将DLL文件加载到进程的虚拟地址空间中。然后使用GetProcAddress函数获取DLL中导出函数的地址,并将其传递给需要调用的函数。通过这种方式,可以在运行时将DLL注入到目标进程中,并且通过调用DLL中的函数来扩展进程的功能。 DLL注入在实际应用中有多种用途。例如,可以使用DLL注入来为某个程序添加额外的功能或修改程序的行为。DLL注入还可以用于实现一些调试和监控的功能。通过注入DLL,可以截获程序的输入和输出,或者在程序执行某些指定的操作时进行额外的处理。 在Delphi中实现DLL注入需要一定的编程知识和技巧。需要考虑目标进程的架构和权限限制,以及如何管理注入的DLL的生命周期和资源管理。同时,还需要处理一些安全性和稳定性方面的问题,以确保注入过程不会对目标进程造成损害或崩溃。 总之,Delphi可以通过调用Windows API函数来实现DLL注入,从而扩展和修改进程的功能。但在实际应用中,需要考虑各种方面的问题,并且遵守相关的法律和规定,以确保注入操作的安全性和合法性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

caz28

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

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

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

打赏作者

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

抵扣说明:

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

余额充值