__declspec(dllimport)的作用到底在哪里呢?



------
我也搞了很久,结论是没什么用
------
当然有区别,__declspec(dllexport)用于导出符号,也就是定义该函数的dll;__declspec(dllimport)用于导入,也就是使用该函数。
因为这个头文件既要被定义该函数的dll包含,也要被使用该函数的程序包含,当被前者包含时我们希望使用__declspec(dllexport)定义函数,当被后者包含时我们希望使用dllimport。于是我们使用
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
这种技巧,在定义该函数的dll中,其编译选项定义了_EXPORTING而使用该函数的程序则没有定义。
------
引用 2 楼 superdiablo 的回复:

当然有区别,__declspec(dllexport)用于导出符号,也就是定义该函数的dll;__declspec(dllimport)用于导入,也就是使用该函数。
因为这个头文件既要被定义该函数的dll包含,也要被使用该函数的程序包含,当被前者包含时我们希望使用__declspec(dllexport)定义函数,当被后者包含时我们希望使用dllimport。于是我们使用
#ifdef _E……

------
兄弟,我是说使用效果在没区别。一个函数,如果你确定要把它导出,就直接用__declspec(dllexport)声明得了,为何还要多此一举地自定义一个预处理器。我说的第一种做法有问题吗?我感觉在使用上完全没有问题。
=========================
有用处的,对于DLL的编写来说,函数当然当然是要导出的,但是,对于引用这个DLL的工程来说,他要用一个头文件来声明DLL中的函数的,此时,由于函数在DLL中,这个函数就要声明为导入了.用预处理器的好处就是对于DLL和引用DLL的工程,我们可以用同一个头文件,只要改一下就行了.

当然,对于一些小的工程,或是你自己做DLL,你当然可以自己手工写头文件,但是对于DLL中函数比较多的,手工再写一个头文件是很麻烦的,如果你的DLL要提供给别人用,你难道还要别人重新写一个头文件?
------
这是一种编程技巧和声明的技巧,根据不同的宏定义进行不同的定义。为何你一定觉得是没用的呢,只是你没用到有用的时候。
------
引用 5 楼 ccpaishi 的回复:

这是一种编程技巧和声明的技巧,根据不同的宏定义进行不同的定义。为何你一定觉得是没用的呢,只是你没用到有用的时候。

------
引用 4 楼 wltg2001 的回复:

兄弟,我是说使用效果在没区别。一个函数,如果你确定要把它导出,就直接用__declspec(dllexport)声明得了,为何还要多此一举地自定义一个预处理器。我说的第一种做法有问题吗?我感觉在使用上完全没有问题。
=========================
有用处的,对于DLL的编写来说,函数当然当然是要导出的,但是,对于引用这个DLL的工程来说,他要用一个头文件来声明DLL中的函……

------
嘿嘿

虽然__declspec(dllimport)有时也可以使 exe 调用 dll 中的函数,但有时会有错误。

编译器会说什么“连接不一致”
------
好像俺在dll中导出,其他地方就声明一个原形,然后就getprocaddr了。

------
首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dllexport)改成__declspec(dllimport)吗?如果发现一次没有写好,你需要修改,那么你再把__declspec(dllimport)改成__declspec(dllexport),然后开始修改你的动态库,你写完了,再交出去的时候,你再把__declspec(dllexport)改成__declspec(dllimport)吗?如果你要改上1000次,你1000次都这样改吗?
那肯定不好,你把时间都花费到这上面,你会说,这活太低级了
------
引用 10 楼 jszj 的回复:

首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dlle……

------
保持程序的接口严谨性,避免歧义
------
你知道一般使用DLL的人要一份函数声明列表的么?
动态加载的除外
这个头文件一般是DLL作者来写的
而这个头文件在作者制作DLL内部也会用到
你作为作者的话可不想多写几分一样的代码吧?
这是出于方便考虑的,脱裤子放屁的是自己,是自己没理解其中真谛
------
引用 13 楼 hurryboylqs 的回复:
你知道一般使用DLL的人要一份函数声明列表的么?
动态加载的除外
这个头文件一般是DLL作者来写的
而这个头文件在作者制作DLL内部也会用到
你作为作者的话可不想多写几分一样的代码吧?
这是出于方便考虑的,脱裤子放屁的是自己,是自己没理解其中真谛

------
你写dll的时候,使用的是dllexport来导出接口,
而别人使用你的dll的时候,相对的来说,是导入接口,即dllimport

使用宏的好处是,只需要一个定义,既可以在你写dll时使用,给别人头文件时也不需要修改相应的定义。
------
技巧问题,怎么用方便就怎么用。。
------
declspec是不是C语言调用标准?
不是普通都是用_stdcallPASCAL标准调用的
偶菜鸟,看不懂

------
引用 4 楼 wltg2001 的回复:

兄弟,我是说使用效果在没区别。一个函数,如果你确定要把它导出,就直接用__declspec(dllexport)声明得了,为何还要多此一举地自定义一个预处理器。我说的第一种做法有问题吗?我感觉在使用上完全没有问题。
=========================
有用处的,对于DLL的编写来说,函数当然当然是要导出的,但是,对于引用这个DLL的工程来说,他要用一个头文件来声明DLL中的函……

------
引用 10 楼 jszj 的回复:

首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dlle……

------
引用 13 楼 hurryboylqs 的回复:

你知道一般使用DLL的人要一份函数声明列表的么?
动态加载的除外
这个头文件一般是DLL作者来写的
而这个头文件在作者制作DLL内部也会用到
你作为作者的话可不想多写几分一样的代码吧?
这是出于方便考虑的,脱裤子放屁的是自己,是自己没理解其中真谛

------
引用 15 楼 jingzhongrong 的回复:

你写dll的时候,使用的是dllexport来导出接口,
而别人使用你的dll的时候,相对的来说,是导入接口,即dllimport

使用宏的好处是,只需要一个定义,既可以在你写dll时使用,给别人头文件时也不需要修改相应的定义。

------
看见你们讨论这么多了,我来吭一声吧,虽然确实如楼主所说使用起来无错,但其区别是很容易被忽略的,只需要简单的步骤验证一下即可:

假设你的A(EXE或DLL)需要调用B(DLL)中的某个导出函数:
__declspec(dllexport) void HelloWorld();

按照楼主的写法,不用宏,在项目A中直接包含这个头文件,编译、运行……OK。

打开Dependency Walker(其它合适的工具也可以),打开A(.EXE或.DLL)文件,在左边树中选择根节点,看看右边有什么内容?对了,A文件也有导出符号"HelloWorld",这是你希望看到的?

但如果使用VC默认提供的宏,这个现象不会发生。

------
引用 22 楼 jameshooo 的回复:

看见你们讨论这么多了,我来吭一声吧,虽然确实如楼主所说使用起来无错,但其区别是很容易被忽略的,只需要简单的步骤验证一下即可:

假设你的A(EXE或DLL)需要调用B(DLL)中的某个导出函数:
__declspec(dllexport) void HelloWorld();

按照楼主的写法,不用宏,在项目A中直接包含这个头文件,编译、运行……OK。

打开Dependency ……

------
这个东西还确实没有仔细地研究过,一直都是相当然的做法,讨论一下也有好处

不过,如果只从字面上来说,楼主的写法就不好,对于DLL来说,那当然是export,而对于使用者来说,那就是import,如果让使用者还是看到export,即使能够成功,也会产生很大疑问甚至误会的

此外,确实需要搞清楚export和import的内部作用是什么,不过,msdn上好像只是说,dllexport和dllimport是microsoft的特别关键字,其它的并没有多说。

建议楼主在微软的论坛里发贴
------
关于 __declspec(dllimport)我刚才找了一下,有人写过相关的文章,大意是说,不用这个也链接器也能工作,不过用它更好。原文是说:
不使用 __declspec(dllimport) 也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。 

你参看一下这个:http://blog.csdn.net/Repeaterbin/archive/2009/06/15/4269666.aspx

------
很久以前我出现过同样的问题,只是偶然才发现多个DLL都导出了相同的符号,经过仔细检查才发现某个头文件用了楼主的这种写法,这个头文件被多个项目引用了,造成了如此结果。不过我的项目都是DLL,你现在没有在EXE中发现导出的符号,是因为编译器在链接时找不到此符号,已经自动忽略了 __declspec(dllexport) 属性。
------
1、变量需要显示地导入。
2、如果不使用 __declspec(dllimport),那么编译生成的代码最终会类似:
  call 0xXXXXXXXX
  0xXXXXXXXX: jmp dword ptr __imp_function
而如果使用了dllimport,连接器会直接生成如下代码,省去中间的间接调用:
  call dword ptr __imp_func
3、在网上看到如果类中用了static变量,也需要使用dllimport。
------
引用 27 楼 jameshooo 的回复:

很久以前我出现过同样的问题,只是偶然才发现多个DLL都导出了相同的符号,经过仔细检查才发现某个头文件用了楼主的这种写法,这个头文件被多个项目引用了,造成了如此结果。不过我的项目都是DLL,你现在没有在EXE中发现导出的符号,是因为编译器在链接时找不到此符号,已经自动忽略了 __declspec(dllexport) 属性。

------
引用 24 楼 jszj 的回复:

这个东西还确实没有仔细地研究过,一直都是相当然的做法,讨论一下也有好处

不过,如果只从字面上来说,楼主的写法就不好,对于DLL来说,那当然是export,而对于使用者来说,那就是import,如果让使用者还是看到export,即使能够成功,也会产生很大疑问甚至误会的

此外,确实需要搞清楚export和import的内部作用是什么,不过,msdn上好像只是说,dllexport和dll……

------
用extern就可以用
关键是__declspec(dllexport)更有效
楼下的详解
------
在你的dll接口文件中如下定义
C/C++ code
#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#else
#define API_DECLSPEC __declspec(dllimport)
#endif



这样你导出的时候就定义_EXPORTING。

但是你提供这个dll给别人用的时候,你直接把这个接口文件和dll给别人就行了
人家用的时候,接口就不需要做改动,一切以提供者的为准,这样避免了一方修改后另外一方也要修改

当你在多人合作的团队中,需要维护大量的这种dll的时候作用就显现出来
------
很久以前我出现过同样的问题,只是偶然才发现多个DLL都导出了相同的符号,经过仔细检查才发现某个头文件用了楼主的这种写法,这个头文件被多个项目引用了,造成了如此结果。不过我的项目都是DLL,你现在没有在EXE中发现导出的符号,是因为编译器在链接时找不到此符号,已经自动忽略了 __declspec(dllexport) 属性。 
 

------
引用 32 楼 diamondhands 的回复:

在你的dll接口文件中如下定义
C/C++ code
#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#else
#define API_DECLSPEC __declspec(dllimport)
#endif



这样你导出的时候就定义_EXPORTING。

但是你提供这个dll……

------
路过看看






蒲友娱乐网
------
支持,楼主好人
------
引用 4 楼 wltg2001 的回复:
兄弟,我是说使用效果在没区别。一个函数,如果你确定要把它导出,就直接用__declspec(dllexport)声明得了,为何还要多此一举地自定义一个预处理器。我说的第一种做法有问题吗?我感觉在使用上完全没有问题。
=========================
有用处的,对于DLL的编写来说,函数当然当然是要导出的,但是,对于引用这个DLL的工程来说,他要用一个头文件来声明DLL中的函数……

------
引用 28 楼 jingzhongrong 的回复:

1、变量需要显示地导入。
2、如果不使用 __declspec(dllimport),那么编译生成的代码最终会类似:
call 0xXXXXXXXX
0xXXXXXXXX: jmp dword ptr __imp_function
而如果使用了dllimport,连接器会直接生成如下代码,省去中间的间接调用:
call dword ptr __imp_func
3、在网上看到如果类……

------
引用 10 楼 jszj 的回复:
首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dllex……

------
#40楼 小技巧:每天回帖即可获得10分可用分!
------
看来,定不定义,问题不是很大,呵呵

主要是两点:
1. 维护问题。写了好代码,以后维护的时候容易
2. 效率上会所有改善
------
楼主显然没有参与过开发过大型项目的经历。等你有了这种经历的时候,你才会发现,啊,原来用宏是这么的重要
------
路过 学习了
------
楼主的想法并没有错,不用宏一样可以完成功能,但是你的思维仅仅局限限在一个一个单一的小工程中,当你把多个工程组织到一个解决方案中,这些工程有些是动态库,当某个工程要调用另外一个动态库工程中的导出函数或类的时候,这个工程必定需要那个函数或类的声明,也就是其头文件, 你是要为每个工程都编写一份头文件,还是让所有需要用到的工程 共用一个头文件呢?如果每个工程都编写一个头文件,一旦头文件要做修改,是不是就得每个都去做修改? 如果工程仅仅只有几个,你还能记住,如果工程有好几百个,你一一去修改? 如果公用一个头文件,那就必须要用到宏。楼主明白了吧?
------
楼主仔细阅读前面的10, 25,26....,讨论就知道了,我不想重复了,优点很显然!
------
引用 44 楼 starnight1981 的回复:

楼主的想法并没有错,不用宏一样可以完成功能,但是你的思维仅仅局限限在一个一个单一的小工程中,当你把多个工程组织到一个解决方案中,这些工程有些是动态库,当某个工程要调用另外一个动态库工程中的导出函数或类的时候,这个工程必定需要那个函数或类的声明,也就是其头文件, 你是要为每个工程都编写一份头文件,还是让所有需要用到的工程 共用一个头文件呢?如果每个工程都编写一个头文件,一旦头文件要做修改,是不是就……

------
引用 42 楼 starnight1981 的回复:

楼主显然没有参与过开发过大型项目的经历。等你有了这种经历的时候,你才会发现,啊,原来用宏是这么的重要

------
引用 41 楼 jszj 的回复:

看来,定不定义,问题不是很大,呵呵

主要是两点:
1. 维护问题。写了好代码,以后维护的时候容易
2. 效率上会所有改善

------
学习了!!
------
学习 学习!

------
marck
------
引用 46 楼 clever101 的回复:

引用 44 楼 starnight1981 的回复:

肯定是为每个工程编写一个头文件,你建一个DLL工程,也得写一个接口头文件吧,到时别人用时,只需要把它连同dll和lib文件交给别人就行。

所有需要用到的工程 共用一个头文件?兄弟,我怀疑这种做法的可行性。先不说能不能共用,就算能共用,如果几百个工程的类和函数都挤在一块,你叫别人找接口声明也不容易啊!有那个必要吗?

------
引用 48 楼 clever101 的回复:
引用 41 楼 jszj 的回复:

看来,定不定义,问题不是很大,呵呵

主要是两点:
1. 维护问题。写了好代码,以后维护的时候容易
2. 效率上会所有改善


多谢大侠,你的意见蛮中肯的!

------
引用 52 楼 starnight1981 的回复:

引用 46 楼 clever101 的回复:

引用 44 楼 starnight1981 的回复:

肯定是为每个工程编写一个头文件,你建一个DLL工程,也得写一个接口头文件吧,到时别人用时,只需要把它连同dll和lib文件交给别人就行。

所有需要用到的工程 共用一个头文件?兄弟,我怀疑这种做法的可行性。先不说能不能共用,就算能共用,如果几百个工程的类和函数都挤在一块,你叫别人找……

------
引用 54 楼 clever101 的回复:

对于你说的,我有些疑问: 10个dll工程中,每个都有导出的类或函数,并且每个都要用到其他dll中的类或函数?请问现实有这样的吗?那岂不是循环依赖?照你的意思,a.dll 要用到b.dll中的类或函数,b.dll中要
用到a.dll中的类或函数,这本身就是系统设计的大忌。

一般而言,系统就是层层调用的,比如界面层调用算法层。你所说的每个都要用到其他dll中的类或函数我还真没见过。

------
引用 55 楼 starnight1981 的回复:

引用 54 楼 clever101 的回复:

对于你说的,我有些疑问: 10个dll工程中,每个都有导出的类或函数,并且每个都要用到其他dll中的类或函数?请问现实有这样的吗?那岂不是循环依赖?照你的意思,a.dll 要用到b.dll中的类或函数,b.dll中要
用到a.dll中的类或函数,这本身就是系统设计的大忌。

一般而言,系统就是层层调用的,比如界面层调用算法层。你所说的每个……

------
这样做的话,那个头文件就可以直接放在调用dll的工程里使用了。。
------
引用 56 楼 starnight1981 的回复:

引用 55 楼 starnight1981 的回复:

引用 54 楼 clever101 的回复:

对于你说的,我有些疑问: 10个dll工程中,每个都有导出的类或函数,并且每个都要用到其他dll中的类或函数?请问现实有这样的吗?那岂不是循环依赖?照你的意思,a.dll 要用到b.dll中的类或函数,b.dll中要
用到a.dll中的类或函数,这本身就是系统设计的大忌。

一般……

------
在导出的地方,必须__declspec(dllexport),在导入的地方,两者并没有多少区别,怎么写都一样。
这个我在几年前还在广州当学徒的时候就已经试过了。

但是有两点:
换个IDE或者说编译器,不能保证还是这个样子;
完整性;

什么是完整性呢,比如为什么所有语言都有true 和 false 呢?!true不就是false了吗?
这就是语言的完整性。
------
引用 59 楼 yang79tao 的回复:

在导出的地方,必须__declspec(dllexport),在导入的地方,两者并没有多少区别,怎么写都一样。
这个我在几年前还在广州当学徒的时候就已经试过了。

但是有两点:
换个IDE或者说编译器,不能保证还是这个样子;
完整性;

什么是完整性呢,比如为什么所有语言都有true 和 false 呢?!true不就是false了吗?
这就是语言的完整性。

------
学习
------
__declspec(dllimport)也许什么实际的作用都没有,这就是LZ究底的地方。

就算是什么实际的作用都没有,个人觉得它还是有作用的,一看这个声明,就知道它是个导入函数。
就好比
#define IN
#define OUT
void strcpy(OUT char * dst, IN char * src); // 这里只是举个例子
由于预处理,IN/OUT在实际编译中不起任何作用,但是在函数原型中由于指明了这样的字眼,
很容易就知道dst是出参,src是入参。
这就是这类“标记”的作用。
而实际上,也许这些标记应该叫做annotation,而且是有实际作用的,编译器能做更多的检查。
http://msdn.microsoft.com/en-us/library/aa383701(VS.85).aspx

个人一点拙见。

------
上面的URL只是给出与dllimport类似概念的东西,而完整的dllimport应该看这个:
http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

------
引用 62 楼 forestdb 的回复:
__declspec(dllimport)也许什么实际的作用都没有,这就是LZ究底的地方。

就算是什么实际的作用都没有,个人觉得它还是有作用的,一看这个声明,就知道它是个导入函数。
就好比
#define IN
#define OUT
void strcpy(OUT char * dst, IN char * src); // 这里只是举个例子
由于预处理,IN/OUT在实际编译中……

------
引用 64 楼 zhouzhipen 的回复:

引用 62 楼 forestdb 的回复:
__declspec(dllimport)也许什么实际的作用都没有,这就是LZ究底的地方。

就算是什么实际的作用都没有,个人觉得它还是有作用的,一看这个声明,就知道它是个导入函数。
就好比
#define IN
#define OUT
void strcpy(OUT char * dst, IN char * src); // 这里只是……

------
关注。。。。
------
什么脱裤子放屁啊~

你就在自己的工程里用这个DLL,当然不会有__declspec(dllimport)的情况。但是如果你的DLL是给别人用的,你只给了个头文件,当然就会执行#define API_DECLSPEC __declspec(dllimport)了,你以为别人也会给你预定义个_EXPORTING宏啊。。。

除非你的意思是说有没有__declspec(dllimport)都一样。
------
不错的帖子,关注一下
------
引用 10 楼 jszj 的回复:
首先得承认,两种写法没有本质的区别,最终的效果是完全一样的。

另外一个问题
如果单从一个方面来说,第二种方法确实有点是“脱裤子放屁式的做法”,不过不知道楼主考虑了没有,如果不这样写,你在写DLL的时候直接写成
__declspec(dllexport) void HelloWorld();
而在你写完之后,要把这个DLL给其他人使用的时候,你再把.h中的__declspec(dllex……

------
mark' mark mark

------
楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。

------
为了重用
------
mark.......
------
看看Windows核心编程
------
引用 67 楼 bluecll 的回复:

什么脱裤子放屁啊~

你就在自己的工程里用这个DLL,当然不会有__declspec(dllimport)的情况。但是如果你的DLL是给别人用的,你只给了个头文件,当然就会执行#define API_DECLSPEC __declspec(dllimport)了,你以为别人也会给你预定义个_EXPORTING宏啊。。。

除非你的意思是说有没有__declspec(dllimpor……

------
关键是什么?参看《编译原理》和 PE文件格式
------
引用 71 楼 r3000 的回复:

楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。

------
引用 77 楼 clever101 的回复:
引用 71 楼 r3000 的回复:

楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。


晕,我没有虚心接受吗?我只是为某些同胞人云亦云感到脸红,自己不动手做个试验就开始嚷嚷了。

------
还是有用的。。。更便于修改和维护、扩展。。。
------
引用 79 楼 beyond_cn 的回复:

还是有用的。。。更便于修改和维护、扩展。。。

------
引用 78 楼 godsmile 的回复:

引用 77 楼 clever101 的回复:
引用 71 楼 r3000 的回复:

楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。


晕,我没有虚心接受吗?我只是为某些同胞人云亦云感到脸红,自己不动手做个试验就开始嚷嚷了。


说楼主固执已经算仁慈了,这样老觉得自己没错的人见多了

对,你试验了,但很多情况压根是你不知道的,你怎么试验?……

------
引用 31 楼 hurryboylqs 的回复:

用extern就可以用
关键是__declspec(dllexport)更有效
楼下的详解

------
引用 4 楼 wltg2001 的回复:
兄弟,我是说使用效果在没区别。一个函数,如果你确定要把它导出,就直接用__declspec(dllexport)声明得了,为何还要多此一举地自定义一个预处理器。我说的第一种做法有问题吗?我感觉在使用上完全没有问题。
=========================
有用处的,对于DLL的编写来说,函数当然当然是要导出的,但是,对于引用这个DLL的工程来说,他要用一个头文件来声明DLL中的函数……

------
引用 72 楼 yujia120 的回复:

为了重用

------
写了一篇博客,有兴趣的朋友可以看看:

总结一下__declspec(dllimport)的作用
------
引用 75 楼 clever101 的回复:

引用 67 楼 bluecll 的回复:

什么脱裤子放屁啊~

你就在自己的工程里用这个DLL,当然不会有__declspec(dllimport)的情况。但是如果你的DLL是给别人用的,你只给了个头文件,当然就会执行#define API_DECLSPEC __declspec(dllimport)了,你以为别人也会给你预定义个_EXPORTING宏啊。。。

除非你的意思……

------
引用 78 楼 godsmile 的回复:

引用 77 楼 clever101 的回复:
引用 71 楼 r3000 的回复:

楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。


晕,我没有虚心接受吗?我只是为某些同胞人云亦云感到脸红,自己不动手做个试验就开始嚷嚷了。


说楼主固执已经算仁慈了,这样老觉得自己没错的人见多了

对,你试验了,但很多情况压根是你不知道的,你怎么试验?……

------
引用 86 楼 imob419 的回复:

引用 75 楼 clever101 的回复:

引用 67 楼 bluecll 的回复:

什么脱裤子放屁啊~

你就在自己的工程里用这个DLL,当然不会有__declspec(dllimport)的情况。但是如果你的DLL是给别人用的,你只给了个头文件,当然就会执行#define API_DECLSPEC __declspec(dllimport)了,你以为别人也会给你预定义……

------
引用 87 楼 james_ 的回复:

引用 78 楼 godsmile 的回复:

引用 77 楼 clever101 的回复:
引用 71 楼 r3000 的回复:

楼主探究真相的精神值得鼓励,但在大家说的很清楚的情况下还不虚心接受就有点固执了。


晕,我没有虚心接受吗?我只是为某些同胞人云亦云感到脸红,自己不动手做个试验就开始嚷嚷了。


说楼主固执已经算仁慈了,这样老觉得自己没错的人见多了

对,……

------
主要作用是你可以导入/导出用同一个符号来表示
------
__declspec(dllexport) 你可以不加试试效果啊~~特别是P/Invoke的方式里面就知道有用了
------
引用 90 楼 an_bachelor 的回复:

主要作用是你可以导入/导出用同一个符号来表示

------
引用 91 楼 wo65432519 的回复:

__declspec(dllexport) 你可以不加试试效果啊~~特别是P/Invoke的方式里面就知道有用了

------
mark
------
學習了
------
也正为此迷惑呢,学习了
------
请教下,问个与dllimport无关的话题
前面在讨论dllimport时,提到了预编译问题,并举了如下例子
#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#else
#define API_DECLSPEC __declspec(dllimport)
#endif

我想问的是这个_EXPORTING宏为什么要在vc的“预编译”选项里定义,而不是在头文件里定义?
谢谢
------
引用 97 楼 njutzyg 的回复:
请教下,问个与dllimport无关的话题
前面在讨论dllimport时,提到了预编译问题,并举了如下例子
#ifdef _EXPORTING
#define API_DECLSPEC __declspec(dllexport)
#else
#define API_DECLSPEC __declspec(dllimport)
#endif

我想问的是这个_EXPORTING宏为……

------
引用 99 楼 lj19881024 的回复:

下面的代码示例显示如何使用 _declspec(dllimport) 将函数调用从 DLL 导入到应用程序中。假定 func1 是驻留在某个 DLL 中的函数,而此 DLL 与包含“主”函数的 .exe 文件是分开的。

不使用 __declspec(dllimport),给出此代码:

C/C++ code

int main(void)
{
func1();
}



……

桂ICP备07017180号