鱼C论坛

 找回密码
 立即注册
查看: 1969|回复: 12

c头文件的问题,

 关闭 [复制链接]
发表于 2014-11-26 09:34:08 | 显示全部楼层 |阅读模式
50鱼币
本帖最后由 小人 于 2014-11-26 01:37 编辑

一个 dll.h  的头文件  
代码如下
#ifndef _DLL_H_       
#define _DLL_H_     //这里定义的_DLL_H_   是什么意思?

#ifdef _EXPORT
#define DECLSPEC  __declspec(dllexport) // 导出      
#else
#define DECLSPEC  __declspec(dllimport) // 导入      
#endif

DECLSPEC  int add(int x,int y);
#endif // _DLL_H_
dll.c文件的代码
#include "dll.h"
#include <stdio.h>
#include <Windows.h>

int add(int x,int y)
{
        return x + y;
}
.h   头文件中的   _DLL_H_   是什么意思?   定义了什么  .为什么后面不用到

导出 的意思是不是 申明函数是给别人调用的
那导入是什么意思

先谢谢各位大大   


最佳答案

查看完整内容

这个就是防止头文件重复包含 _DLL_H_ 只是一个标记,你随便怎么写 #ifndef _DLL_H_ //如果没定义过 _DLL_H_ #define _DLL_H_ //那么就定义 _DLL_H_ #ifdef _EXPORT //如果定义了 _EXPORT #define DECLSPEC __declspec(dllexport) // 导出 #else //否则 #define DECLSPEC __declspec(dllimport) // 导入 #endif DECLSPEC int add(int x,int y); #endif // _D ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-26 09:34:09 | 显示全部楼层
本帖最后由 machimilk 于 2014-11-26 10:11 编辑

这个就是防止头文件重复包含 _DLL_H_ 只是一个标记,你随便怎么写

#ifndef _DLL_H_    //如果没定义过     _DLL_H_   
#define _DLL_H_     //那么就定义 _DLL_H_
#ifdef _EXPORT      //如果定义了 _EXPORT
#define DECLSPEC  __declspec(dllexport) // 导出      
#else                     //否则
#define DECLSPEC  __declspec(dllimport) // 导入      
#endif

DECLSPEC  int add(int x,int y);
#endif // _DLL_H_

如果这个头文件被你交叉包含,(第二次包含的时候他发现你第一次定义过_DLL_H_)
那么他就不在包含了,这样就解决了不小心 交叉包含导致各种报错的问题

dllimport的解释给你摘抄了一段 你仔细看一下吧
----------------------------------------------------------------------------------------

1。用于静态链接:
      给系统调用静态链接的时候,知道导出函数的地址在哪里dll文件名是什么,静态链接编译的时候,
由编译器把这些信息加入到exe文件中
    静态调用方式的顺利进行需要完成两个动作:

  (1)告诉编译器与DLL相对应的.lib文件所在的路径及文件名,#pragma comment(lib,"dllTest.lib")就是起这个作用。

  程序员在建立一个DLL文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了DLL 导出函数的符号名及序号(并不含有实际的代码)。在应用程序里,.lib文件将作为DLL的替代文件参与编译。

  (2)声明导入函数,extern "C" __declspec(dllimport) add(int x,int y)语句中的__declspec(dllimport)发挥这个作用。

   静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用 程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE 文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在 EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL 函数的动态链接。这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。

2。用于导出dll中的全局变量本身而不是dll中全局变量的地址(指针变量一个)
      DLL定义的全局变量可以被调用进程访问;DLL也可以访问调用进程的全局数据,我们来看看在应用工程中引用DLL中变量的例子

/* 文件名:lib.h */

#ifndef LIB_H

#define LIB_H

extern int dllGlobalVar;

#endif


/* 文件名:lib.cpp */

#include "lib.h"

#include <windows.h>


int dllGlobalVar;


BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

dllGlobalVar = 100; //在dll被加载时,赋全局变量为100

break;

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}


;文件名:lib.def

;在DLL中导出变量

LIBRARY "dllTest"

EXPORTS

dllGlobalVar CONSTANT

;或dllGlobalVar DATA

GetGlobalVar

  从lib.h和lib.cpp中可以看出,全局变量在DLL中的定义和使用方法与一般的程序设计是一样的。若要导出某全局变量,我们需要在.def文件的EXPORTS后添加:

变量名 CONSTANT   //过时的方法

  或

变量名 DATA     //VC++提示的新方法

在主函数中引用DLL中定义的全局变量:

#include <stdio.h>

#pragma comment(lib,"dllTest.lib")

extern int dllGlobalVar;

int main(int argc, char *argv[])

{

printf("%d ", *(int*)dllGlobalVar);

*(int*)dllGlobalVar = 1;

printf("%d ", *(int*)dllGlobalVar);


return 0;

}

  特别要注意的是用extern int dllGlobalVar声明所导入的并不是DLL中全局变量本身,而是其地址,应用程序必须通过强制指针转换来使用DLL中的全局变量。这一点,从* (int*)dllGlobalVar可以看出。因此在采用这种方式引用DLL全局变量时,千万不要进行这样的赋值操作:

dllGlobalVar = 1;

  其结果是dllGlobalVar指针的内容发生变化,程序中以后再也引用不到DLL中的全局变量了。

  在应用工程中引用DLL中全局变量的一个更好方法是:

#include <stdio.h>

#pragma comment(lib,"dllTest.lib")

extern int _declspec(dllimport) dllGlobalVar; //用_declspec(dllimport)导入

int main(int argc, char *argv[])

{

printf("%d ", dllGlobalVar);

dllGlobalVar = 1; //这里就可以直接使用, 无须进行强制指针转换

printf("%d ", dllGlobalVar);

return 0;

}

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
拈花小仙 + 5 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-11-26 09:41:35 | 显示全部楼层
@小甲鱼 @仰望天上的光  @拈花小仙
大神们辛苦了  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-11-26 10:50:31 | 显示全部楼层
machimilk 发表于 2014-11-26 01:34
这个就是防止头文件重复包含 _DLL_H_ 只是一个标记,你随便怎么写

#ifndef _DLL_H_    //如果没定义过   ...

太谢谢 你了   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-26 23:55:02 | 显示全部楼层
mark下,dll一点都不懂呢,趁机会学习学习,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-28 11:07:17 | 显示全部楼层
虽然不会,但还是要标记下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:46:01 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:46:46 | 显示全部楼层
学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:47:21 | 显示全部楼层
:ton:呵呵
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:47:56 | 显示全部楼层
希望快快长大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:49:25 | 显示全部楼层
头文件的定义格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-11-30 01:50:07 | 显示全部楼层
我是进来学习的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-12-7 10:08:55 | 显示全部楼层
学习下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-18 13:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表