__declspec(dllexport) 与 .def

2024-01-30 20:58
文章标签 def declspec dllexport

本文主要是介绍__declspec(dllexport) 与 .def,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

__declspec(dllexport) 与 .def

 

模块定义 (.def) 文件是包含一个或多个描述各种 DLL 属性的 Module 语句的文本文件。
1、二者的目的都是将公共符号导入到应用程序中或从 DLL 导出函数。
2、添加 __declspec(dllexport)是为了提供不使用.def文件从 .EXE 或 .DLL 导出函数的简单方法。
3、如果不使用 __declspec (dllimport) 或 __declspec(dllexport) 导出 DLL 函数,则 DLL 需要.def文件。
4、并不是任何时候选择添加 __declspec(dllexport)而放弃.def的方式都是好的。如果DLL是提供给VC++用户使用的,只需要把编译DLL时产生的.lib提供给用户,它可以很轻松地调用你的DLL。但是如果DLL是供VB、PB、Delphi用户使用的,那么会产生一个小麻烦。因为VC++对于__declspec(dllexport) 声明的函数会进行名称转换,如下面的函数: 
     __declspec(dllexport) int __stdcall IsWinNT() 
     会转换为IsWinNT@0,这样你在VB中必须这样声明: 
     Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long 
     @的后面的数由于参数类型不同而可能不同。这显然不太方便。所以如果要想避免这种转换,就要使用.def文件方式。

模块定义 (.def) 文件为 链接器 提供有关被链接程序的导出、属性及其他方面的信息。生成 DLL 时,.def 文件最有用。由于存在可代替模块定义语句使用的 链接器 选项,通常不需要 .def 文件。也可以将 __declspec(dllexport) 用作指定导出函数的手段。在 链接器 阶段可以使用 /DEF(指定模块定义文件)链接器选项调用 .def 文件。如果生成的 .exe 文件没有导出,使用 .def 文件将使输出文件较大并降低加载速度。

定义格式编辑

.def 文件中的第一条 LIBRARY 语句不是必须的,但LIBRARY 语句后面的 DLL 的名称必须正确,即与生成的动态链接库的名称必须匹配。此语句将 .def 文件标识为属于 DLL。 链接器将此名称放到 DLL 的 导入库中。
EXPORTS 语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 到 N,其中 N 是 DLL 导出函数的个数。
LIBRARY BTREE
EXPORTS
Insert @1
Delete @2
Member @3
Min @4
如果使用 MFC DLL 向导创建 MFC DLL,则向导将为您创建主干 .def 文件并将其自动添加到项目中。添加要导出到此文件的函数名。对于非 MFC DLL,必须亲自创建 .def 文件并将其添加到项目中。
如果导出 C++ 文件中的函数,必须将修饰名放到 .def 文件中,或者通过使用外部“C”定义具有标准 C 链接的导出函数。如果需要将修饰名放到 .def 文件中,则可以通过使用 DUMPBIN 工具或 /MAP  链接器选项来获取修饰名。请注意,编译器产生的修饰名是编译器特定的。如果将 Visual C++ 编译器产生的修饰名放到 .def 文件中,则链接到 DLL 的应用程序必须也是用相同版本的 Visual C++ 生成的,这样调用应用程序中的修饰名才能与 DLL 的 .def 文件中的导出名相匹配。

DEF文件还是很简单的,先举一个简单的例子(取决我的一个项目文件):
  1. ; AIDemo_CPP.def
  2. ; 该文件定义了DLL要导出的函数接口名

  3. LIBRARY        "AIDemo_CPP"

  4. EXPORTS
  5.     AI_Create             @1
  6.     AI_Destroy            @2
  7.     AI_Init               @3
  8.     AI_SetDepth           @4
  9.     AI_SetTimeLimit       @5
  10.     AI_PlaceChessman      @6
  11.     AI_Play               @7
  12.     AI_IsFull             @8
  13.     AI_IsWin              @9
  14.     AI_QuerySituation     @10
  15.     AI_QueryAuthorInfo    @11
  16.     AI_QueryAIInfo        @12

  17. ; Ok, over
复制代码

DLL中用来定义给用户使用的API时,可以写一个.def文件

我知道的有三种方式
1.
#ifndef __DELAYLOADLIB_H__
#define __DELAYLOADLIB_H__

#ifdef DELAYLOADLIB_EXPORTS
#    define DELAYLOADLIBAPI __declspec(dllexport)
#else
#    define DELAYLOADLIBAPI __declspec(dllimport)
#endif /* DELAYLOADLIB_EXPORTS */

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
DELAYLOADLIBAPI int fnLib();
DELAYLOADLIBAPI int fnLib2();
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __DELAYLOADLIB_H__ */


2. 写def用lib /def[:filename]命令处理

3. 在IDE的link选项指定def文件

def的目的是为了使用lib工具产生dll的引入库 供客户端编译时使用

这篇关于__declspec(dllexport) 与 .def的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/661533

相关文章

C++常见异常汇总(三): fatal error: google/protobuf/port_def.inc

文章目录 1、fatal error : sw/redis++/redis.h2、fatal error: dwarf.h: No such file or directory3、fatal error: elfutils/libdw.h: No such file or directory4、fatal error: libunwind.h: No such file or directo

DLL 中 .def文件的使用

DLL中导出函数的声明有两种方式:一种为在函数声明中加上__declspec(dllexport),这里不再举例说明;另外一种方式是采用模块定义(.def) 文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。             首先创建 一个DLL程序,.cpp中 int __stdcall Add(int numa, int numb) {

dll中的模块定义文件.def

模块定义 (.def) 文件为链接器提供有关被链接程序的导出、属性及其他方面的信息。生成 DLL 时,.def 文件最有用。由于存在可代替模块定义语句使用的链接器选项,通常不需要 .def 文件。也可以将 __declspec(dllexport) 用作指定导出函数的手段。在链接器阶段可以使用 /DEF(指定模块定义文件)链接器选项调用 .def 文件。如果生成的 .exe 文件没有导

【Python】Python_learning1:python的def函数用法

一、函数调用的含义 函数是类似于可封装的程序片段。允许你给一块语句一个名字,允许您在你的程序的任何地方使用指定的名字运行任何次数。python中有许多内置函数,如len和range。函数概念可能是任何有价值软件中最重要的块(在任何编程语言中)。 二、定义函数使用def关键字 在这个关键字之后是标识函数的名字;其次是在一对括号中可以附上一些变量名;最后在行的末尾是冒号。接下来是语句

C++的dllexport和dllimportnbsp;nbsp;…

C++的dllexport和dllimport: __declspec(dllexport) 声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类 __declspec(dllimport)

(转载)__declspec(dllimport)的作…

是时候总结一下__declspec(dllimport)的作用了。可能有人会问:__declspec(dllimport)和__declspec(dllexport)是一对的,在动态链接库中__declspec(dllexport)管导出,__declspec(dllimport)管导出,就像一个国家一样,有出口也有进口,有什么难理解的呢?这是一种很自然的思路,开始我也是这样理解。

__declspec(dllexport)

原文地址:__declspec(dllexport) 作者:独自等待 先看代码:以下是在dev-c++里建立自已的dll时的dll.h里面的代码,这里面有一个:_declspec(dllexport) #ifndef _DLL_H_ #define _DLL_H_//防重复定义 #if BUILDING_DLL # define DLLIMPORT __declspec (dllexp

scala 中的def/val/lazy val/的区别,call-by-value/call-by-name

本文简述在Scala中def、val和lazy val的区别 关于val、lazy val和def的概念在此不多说,假设在 ~/Desktop 目录下有有一个 test.dat 文件,内容为: content 1 直接来看在REPL中的效果: 使用val 如果 ~/Desktop/test.dat 文件不存在 scala> val content1 = Source.fr

async def 异步编程

Python异步函数即async必须在普通函数的命名前加上async 参考文档: 第二十一章 异步编程_async def-CSDN博客 三 示例一 #!/usr/bin/env python3import asyncioimport socketfrom keyword import kwlistMAX_KEYWORD_LEN = 4 1async def probe(doma

LINK2019: unresolved external symbol __declspec(dllimport) public: class std::basic_string的解决方案

事情的起因是用VS2003编译ogre的时候,写了一个demo,死活链接不过,总是提示,unresolved external symbol "__declspec(dllimport) public: class std::basic_string,很郁闷的,甚至一度想要放弃VS2003算了,但是后来想想还是再找一找,最后在一国外论坛找到了解决方法,原文是这样的:   You should