dll 学习相关知识总结

Window动态库相关知识

1.先从一个dll工程创建开始

//add.h

#ifdef DLLEXPORT

#define DLLAPI __declspec(dllexport)

#else

#define DLLAPI __declspec(dllimport)

#endif

extern "C"

{

    DLLAPI int add(int ra, int rb);

};

 

//add.cpp

#include "add.h"

int add(int ra, int rb)

{

    return ra+rb;

}

第一行的宏定义是为了使dll创建和使用模块共用一个头文件,便于项目的维护。__declspec(dllexport)关键字的作用是导出dll中的函数,变量等等,__declspec(dllimport)的作用,就我目前所知道,是为了让执行模块更好的区别是否为dll导出函数等,具体是否有其他方面的作用,还在学习中。

 

至于为什么使用extern “C”,是为了考虑到c和c++模块之间的兼容问题,我们应该知道C++编译器之所以支持重载,关键技术就是对函数进行改名,使之标识函数名和参数类型两个方面的信息,使用上面的关键字,就是明确的告知编译器,我想要以c的方式编译这些的文件,编译器接到这个信息后便不会为之改名了。如果执行模块是c编写的,函数不改名,而dll模块是c++编写的,则要改名,没有使用这个关键字进行声明,执行模块在调用dll的时候便会报错。需要注意的是这个关键字只能用在c++编写的dll中。

 

 

2.关于在dll中申请内存空间的问题。

如果在dll中有这么一个函数,用来申请内存,

void* AllocMemory()

{

    void*  p = malloc(1000);

    return p;

}

 

在exe执行模块中进行如下调用

 

int main

{

    void* p = AllocMemory();

    free(p);

    return 0;

}

上面的做法有可能出现错误的(具体什么原因,不是特别清楚,各位同学有知道的,可以跟我说下),防止可能出现的问题,最有效的方法就是做到谁申请,谁释放的原则,也就是说,在dll提供内存申请接口的同时,也要提供一个释放接口,释放的方式要一直(malloc,relloc,calloc使用free释放,而new,用delete)。具体方法如下:

Dll模块中添加释放内存接口:

void* AllocMemory()

{

    void*  p = malloc(1000);

    return p;

}

 

void FreeMemory(void *p)

{

    free(p);

}

 

执行模块进行如下调用

int main

{

    void* p = AllocMemory();

    FreeMemory(p);

 

    return 0;

}

 

知识补充:

Dll载入到进程就是虚拟内存映射的过程,此时所有的内存申请,对象创建都是在执行模块的地址空间中完成的,所以在dll中申请的空间,务必在dll完成释放,否则在执行进程结束前,这部分空间一直保持着占用状态。

你可能感兴趣的:(C/VC++)