2009年4月8日星期三

【原】模块间(dll, exe)使用导出变量、静态变量和外部变量的试验与结论

// Dll头文件声明

AFX_EXT_DATA int D1_nCount;

extern int D1_nCountE;

static int D1_nCountS = 0;

AFX_EXT_API int D1_GetCount();

// 结论:多模块调用时,或重复调用时,模块内的静态变量是唯一的,不会重复分配内存
int nCount = D1_GetCount();
nCount = D2_GetCount();
nCount = D1_GetCount();

// 结论:dll中声明的静态变量在每个使用的cpp下均有一份拷贝,多模块更是如此(静态变量在编译时会分别拷贝)
nCount = D1_nCountS;
D1_nCountS = 2;

// 结论:dll中声明的外部变量不能用于其他模块,链接失败(基地址都不一样,肯定不行)
nCount = D1_nCountE;
D1_nCountE = 2;

// 结论:dll中导出的数据到处都可以用,在模块内部只有一份拷贝,每个用到的模块各有一份拷贝
nCount = D1_nCount;
D1_nCount = 2;

其实上面有些结论是不太正确的,以下后续试验得出了新的结论:

// Dll头文件声明

#ifdef DLL2_EXPORTS
#define D2_API __declspec(dllexport)
#else
#define D2_API __declspec(dllimport)
#endif

D2_API extern int D2_nCount;

// 结论:dll中导出变量在其所在模块为导出,在其他模块必须为导入
// 结论:dll中导出的外部变量到处都可以用,在所有模块中都只有一份拷贝
// 结论:dll中导出的变量到处都可以用,在所有模块中都只有一份拷贝,
// 但是在其所在模块只能包含一次(否则为重定义),所以只能声明为外部变量

nCount = D2_nCount;
D2_nCount = 2;

// 总结论:dll中的变量一般情况下是以函数接口形式导出,
// 但在某些情况下可能需要在模块间直接使用,那么就有两种方法:
// 如果需要该变量在每个模块都有一份拷贝,那么可以使用static声明,
// 不过这种用途一般比较少。。还有就是使用__declspec(dllexport) extern声明,
// 一般都是需要各个模块公用一份拷贝,注意在其他模块使用时需要用
// __declspec(dllexport)导入该变量,否则就又是导出了,而且没有实现

没有评论:

发表评论