DLL输入和输出函数—dllinport与dllexport
Microsoft特殊处
dllimport和dllexport存储类修饰符是C语言的Microsoft特殊处扩充。这些修饰显式定义了DLL的客户界面(可执行的文件或另外的DLL)。说明为dllexport的函数消除了一个模块定义(.DLL)文件的需要。你可以为数据和对象使用dllimport和dllexport修饰符。
dllimport和dllexport存储类修饰符必须与扩充的属性语法关键字__declspec一起使用,下面是这样的例子:
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
DllExport void func();
Dllexport int i = 10;
DllExport int j;
DllExport int n;
有关扩充的存储类修饰符的语法的指定信息,参见第3章“说明和类型”中的“扩充的存储类型属性”。
Microsoft特殊处结束
定义和说明
Microsoft特殊处
DLL界面指的是系统中某个程序中输出的所有已知项(函数和数据);也就是所有说明为dllimport或dllexport的所有项。包括在DLL界面中的所有说明必须指定为dllimport或dllexport属性。但该定义只能指定dllexport属性。例如,如下函数定义生成一个编译器错误:
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
DLLImport int func()/*错误:在定义中禁止dllimport*/
{
return 1;
}
下面代码也产生一个错误:
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
DllImport int i=10; /*错误:这是一个定义*/
但如下是正确的语法:
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
DllExport int i=10; /*正确:这是一个输出定义*/
dllexport的使用隐含一个定义,而dllimport隐含一个说明。你必须对dllexport使用extern关键字强制为一个说明;否则,隐含是一个定义。
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
extern DllImport int k; /*这是正确的并隐含一个说明*/
Dllimport int j;
Microsoft特殊处结束
用dllexport和dllimport定义联编函数
Microsoft特殊处
你可以用dllexport属性定义一个联编函数,在这种情况下,该函数总是被实例化和被输出,无论程序中的任何模块引用该函数。该函数假定是被另一程序输入。
你也可以用dllimport属性说明一个函数为联编函数,在这种情况下,该函数可以被伸展(从属于/Ob(联编)编译器选项规格)但不能被实例化。在特殊情况中,如果一个联编输入的函数的地址被占用,该函数的地址保留在返回的DLL中。这个行为和占用一个非联编输入的函数的地址相同。在联编函数中的静态局部数据和字符串在DLL和象在单个程序中似的客户(也就是,一个没有DLL界面的可执行文件)之间维护相同的标识符。
在进行提供输入的联编函数的练习时要小心,例如,如果你修改DLL,不要假设该客户使用该DLL的改变的版本。为了保证你加载适当的DLL版本,重新建立该DLL的客户。
Microsoft特殊处结束
dllimport/dllexport的规则和限制
Microsoft特殊处
* 如果你说明一个函数没有dllimport或dllexport属性,该函数不认为是DLL界面的部分。因此,该函数的定义必须出现在该模块中或相同程序的另一个模块中。为了使该函数成为DLL界面部分,必须在其它模块中以dllexport说明该函数的定义;否则,在建立客户时产生一个链接器错误。
* 如果你的程序的单个模块包含相同函数的dllimport和dllexport说明,那么dllexport属性的优先级比dllimport属性的优先级高。但编译器产生一个警告。例如:
#define DLLimport __declspec(dllimport)
#define DLLexport __declspec(dllexport)
DllImport void func1(void); DllExport void func1(void);/*警告:dllexport更优先*/
* 你不能用一个以dllimport属性说明的数据对象的地址初始化一个静态数据指针。
例如,如下代码产生一个错误:#define DllImport __declspec(dllimport)#define DllExport __declspec(dllexport) DllImport int i ; . . . int *pi=&i; /* 错误 */ void func2() { static int *pi=&i; /* 错误 */ }
* 用一个dllimport说明的函数的地址初始化一个静态函数指针,设置该指针为该DLL输入形实替换程序(一个转换控制到该函数的代码块)而不是该函数的地址。如下赋值不产生错误消息:
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
DllImport void func1(void)
. . . static void (*pf)(void)=&func1;/* 没有错误 */
void func2()
{
static void (*pf)(void)=&func1;/* 没有错误 */
}
* 因为在一个对象的说明中包括dllexport属性的程序必须提供这个对象的定义,你可以用一个dllexport函数的地址初始化一个全局或局部静态函数指针。类似地,你可以用一个dllexport数据对象的地址初始化一个全局或局部静态数据指针。例如:
#define DllImport __declspec(dllimport)
#define DllExport __declspec(dllexport)
DllImport void func1(void);
DllImport int i;
DllExport void func1(void);
DllExport int i;
. . .
int *pi=&i; /* 正确 */
static void(*pf)(void) = &func1;
/* 正确 */
void func2()
{
static int *pi=i; /* 正确 */
static void (*pf)(void) = &func1; /* 正确 */
}
DLL输入和输出函数—dllinport与dllexport的更多相关文章
- C语言的基本输入与输出函数(全解)
C语言的基本输入与输出函数 1.1.1 格式化输入输出函数 Turbo C2.0 标准库提供了两个控制台格式化输入. 输出函数printf() 和scanf(), 这两个函数可以在标准输入输出设备上以 ...
- C语言的基本输入与输出函数
C语言中最常用最基础的输入输出函数:printf() 和 scanf(); 例子: #import <Foundation/Foundation.h> int main(int argc, ...
- python 字符串输入、输出函数print input raw_input
一.输出print print输出是以不带引号的输出.(用户所见的输出) 二.input() 和 raw_input()输入函数 raw_input()会把输入数据转换成字符串形式: ------ ...
- C语言中输入输出函数
1.1.1 格式化输入输出函数Turbo C2.0 标准库提供了两个控制台格式化输入. 输出函数printf() 和scanf(), 这两个函数可以在标准输入输出设备上以各种不同的格式读写数据.pri ...
- 动态链接库(dll) __declspec(dllimport) __declspec(dllexport)
一. __declspec(dllexport) Microsoft 在 Visual C++ 的 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib ...
- 忙里偷闲( ˇˍˇ )闲里偷学【C语言篇】——(3)输入输出函数
一.基本的输入和输出函数的用法 1.printf() //屏幕输出 用法: (1)printf("字符串\n"); (2)printf("输出控制符", 输出 ...
- __declspec(dllexport)和__declspec(dllimport) (——declspec方法创建dll的方法已验证ok)
转载:https://www.cnblogs.com/chengbing2011/p/4084125.html __declspec(dllimport)和__declspec(dllexport)经 ...
- python基本输入输出函数
python程序设计中有三个重要的基本输入.输出函数,用于输入.转换和输出,分别是input(),eval(),print() 1,input()函数 """ input ...
- DLL编程学习
原文出处:http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html DLL编写教程 半年不能上网,最近网络终于通了,终于可以更新博 ...
随机推荐
- android怎么换背景图片
我不晓得一般是怎么做的,但是至少可以用两种方法,一种是用一个全屏的ImageView来当作背景,通过修改imageview来修改背景图片,一种是将你xml中最外层的那个布局,LinerLayout之类 ...
- [sinatra] Just Do It: Learn Sinatra, Part One Darren Jones
1. Install sinatra gem gem install sinatra --no-ri --no-rdoc 2. Basic App #!/usr/bin/ruby require 's ...
- 转:Eclipse常用开发插件
以下是我整理的自己开发过程中的常用Eclipse插件,按字母排序: (1) AmaterasUML 介绍:Eclipse的UML插件,支持UML活动图,class图,sequen ...
- mysql的sql文件的备份与还原
1.备份 $mysqldump –u root –p*** dbname > filename.sql 2.还原 前提是数据库必须存在 $mysql –u root –p*** dbname ...
- CentOS 7安装Gnome GUI 图形界面
当你安装centos服务器版本的时候,系统默认是不会安装 CentOS 的图形界面程序的,比如:gnome或者kde, 那么如果你想在图形界面下工作的话,可以手动来安装CentOS Gnome GUI ...
- Docker centos 安装syslog
在通常的Linux服务器中,有一些服务本身没有日志,只能通过 tail -f /var/log/messages来查看其运行日志,比如nrpe server.但是,如果想在docker容器中实现这个功 ...
- PHP String 函数
[http://www.w3school.com.cn/php/php_ref_string.asp ] PHP String 简介 String 字符串函数允许您对字符串进行操作. 安装 Strin ...
- ACE的接受器(Acceptor)和连接器(Connector):连接建立模式
ACE_Acceptor工厂的open()方法,或是它的缺省构造器(它实际上会调用open()方法),来开始被动侦听连接.当接受器工厂的open()方法被调用时,如果反应堆单体还没有被实例化,open ...
- combobox中动态加入几个checkbox,实现下拉框多选
combobox中动态加入几个checkbox,实现下拉框多选,将一个checkbox选中时其内容就会在combobox中显示出来,将另一个checkbox选中时其内容会跟在第一个checkbox的内 ...
- 利用Session实现一次验证码
Session可避免表单的重复提交:实现一次表单提交,可避免恶意提交: 1.首先建立一个Servlet类:ValidateColorServlet,里边有获取验证码的方法,并且验证码是大小写区分: p ...