首页 > 其他分享 >msvc的__declspec(dllexport)

msvc的__declspec(dllexport)

时间:2024-09-30 15:46:46浏览次数:7  
标签:__ 符号 导出 declspec MyLibrary msvc dllexport

一、__declspec(dllexport)的含义

_declspec(dllexport) 是 Microsoft 特定的一个编译器扩展,用于指示编译器将符号导出到动态链接库(DLL)中。它并不是一个标准 C++ 关键字或语法,而是 __declspec 关键字的一个特定用法。__declspec 是 "declare specifier" 的缩写,表示声明说明符。dllexport 则是 "DLL export" 的缩写,表示将符号导出到 DLL 中。

因此,__declspec(dllexport) 的含义可以分解为:

  • __declspec:声明说明符,用于指定某些属性或行为。
  • dllexport:DLL 输出,表示将符号导出到 DLL 中。

使用场景

  1. 创建 DLL: 当您创建一个 DLL 并希望某些函数或变量可以被外部模块调用时,您可以使用 __declspec(dllexport) 来导出这些符号。

  2. 声明导出的符号: 使用 __declspec(dllexport) 声明的函数或变量将在编译时生成相应的导出信息,使得这些符号可以被其他模块识别和使用。

二、__declspec(dllexport)具体指示构建工具链中哪些程序的哪些行为

 

__declspec(dllexport)`的作用主要体现在编译和链接阶段,具体指示构建工具链中编译器和链接器的行为。

编译器行为(如 cl.exe)

1. 符号导出:
- 当编译器遇到使用 __declspec(dllexport)声明的符号(例如函数或变量)时,它会将这些符号标记为导出符号。这意味着这些符号将在生成的对象文件中被标记为需要导出。
- 编译器会在对象文件的符号表中添加相应的导出信息,使得这些符号在链接阶段可以被识别为导出符号。

链接器行为(如 link.exe)

1. 创建导出表:
- 链接器在生成 DLL 时,会根据对象文件中的导出符号信息创建导出表。导出表包含所有被标记为导出的符号,使得这些符号可以被其他模块识别和使用。
- 导出表是 DLL 文件的一部分,包含符号的名称、地址等信息。

2. 生成导出库文件:
- 链接器还会生成一个导出库文件(`.lib` 文件),该文件包含导出符号的引用信息。这个库文件用于在编译和链接使用该 DLL 的应用程序时提供符号解析。
- 应用程序在链接阶段使用这个导出库文件来解析对 DLL 中导出符号的引用。

### 示例

假设我们有以下代码:

cpp

// MyLibrary.h
#ifndef MYLIBRARY_H
#define MYLIBRARY_H

#ifdef MYLIBRARY_EXPORTS
#define MYLIBRARY_API __declspec(dllexport)
#else
#define MYLIBRARY_API __declspec(dllimport)
#endif

MYLIBRARY_API void MyFunction();

#endif // MYLIBRARY_H

cpp

// MyLibrary.cpp
#include "MyLibrary.h"

void MyFunction() {
// Function implementation
}

 

构建过程:

1. 编译阶段:
- 使用 cl.exe 编译 MyLibrary.cpp:
sh

cl /c /DMYLIBRARY_EXPORTS MyLibrary.cpp

 

- 编译器将 MyFunction 标记为导出符号,并在生成的对象文件 MyLibrary.obj 中包含相应的导出信息。

2. 链接阶段:
- 使用 link.exe 将对象文件链接为 DLL:
sh

link /DLL /OUT:MyLibrary.dll MyLibrary.obj


- 链接器根据对象文件中的导出符号信息创建导出表,并将其包含在生成的 `MyLibrary.dll` 中。
- 链接器还生成一个导出库文件 `MyLibrary.lib`,用于在其他模块中链接和使用该 DLL。

总结

__declspec(dllexport)` 主要影响编译器和链接器的行为:

编译器:标记符号为导出符号,并在对象文件中包含相应的导出信息。
链接器:创建导出表并生成导出库文件,使得这些符号可以被其他模块识别和使用。

 

三、g++类似的行为

 

在 Linux 下使用 g++ 构建共享库(Shared Library)时,虽然没有直接等价于 __declspec(dllexport)的关键字,但可以通过其他方法实现类似的导出符号功能。主要有以下几种方式:

1. 使用 __attribute__((visibility("default")))

GCC 提供了 __attribute__机制,可以用来控制符号的可见性。__attribute__((visibility("default")))类似于 __declspec(dllexport),用于将符号导出到共享库中。

示例:

cpp

// MyLibrary.h
#ifndef MYLIBRARY_H
#define MYLIBRARY_H

#if defined(__GNUC__) && __GNUC__ >= 4
#define MYLIBRARY_API __attribute__((visibility("default")))
#else
#define MYLIBRARY_API
#endif

MYLIBRARY_API void MyFunction();

#endif // MYLIBRARY_H

 

 

cpp

// MyLibrary.cpp
#include "MyLibrary.h"

void MyFunction() {
// Function implementation
}

 

构建共享库:

sh

g++ -fPIC -shared -o libMyLibrary.so MyLibrary.cpp

 



2. 使用版本脚本(Version Script)

版本脚本是一种更为灵活的方法,可以精确控制哪些符号被导出。通过在链接阶段指定版本脚本,可以明确指定哪些符号应该被导出。

示例:

创建版本脚本 `MyLibrary.map`:

{
global:
MyFunction;
local:

};

 

构建共享库:

sh

g++ -fPIC -shared -o libMyLibrary.so MyLibrary.cpp -Wl,--version-script=MyLibrary.map

 

3. 默认导出所有符号

在构建共享库时,可以通过编译器选项导出所有符号。不过,这种方法不推荐用于大型项目,因为它会导出所有符号,可能导致命名冲突。

 构建共享库:

sh

g++ -fPIC -shared -o libMyLibrary.so MyLibrary.cpp

 

总结

在 Linux 下使用 g++构建共享库时,可以通过以下几种方法实现导出符号的功能:

1. __attribute__((visibility("default"))):类似于 __declspec(dllexport),用于导出特定符号。
2. 版本脚本:通过版本脚本精确控制导出符号。
3. 默认导出所有符号:不推荐,但可以通过编译器选项导出所有符号。

这些方法可以根据具体需求选择使用,以便在 Linux 下实现与 __declspec(dllexport)`类似的功能。

标签:__,符号,导出,declspec,MyLibrary,msvc,dllexport
From: https://www.cnblogs.com/xietianjiao/p/18441977

相关文章

  • unity编辑器绘制扇形
    使用UnityEditor.Handles.DrawSolidArc usingUnityEngine;usingUnityEditor;publicclassDrawSectorHandles:MonoBehaviour{publicfloatradius=5f;//扇形半径publicfloatangle=90f;//扇形角度publicColorarcColor=Color.red;/......
  • Google-Hacker-搜索引擎使用技巧
    搜索引擎使用技巧1.谷歌关键字汇总12.Googlehacker汇总网站3.bing搜索引擎示例4.google关键字最新5.bing高级搜索关键字6.谷歌语法生成网站1.Google常用语法1.1常用关键字说明site指定域名site:*.edu.cn限定域名后缀为edu.cn的网站inurlURL中存在的关键字inurl:......
  • rabbitmq部署 从单节点到集群,到镜像
    想搭建镜像,也需要从单节点一步步往下,按顺序执行,应该不会有什么问题准备工作:1、设置主机名(根据自己主机的情况设置,主机名不能有.)hostnamectlset-hostnamenode01###节点01hostnamectlset-hostnamenode02###节点02hostnamectl--prettyhostnamectl-......
  • Drain算法-笔记
    简介论文链接:https://jiemingzhu.github.io/pub/pjhe_icws2017.pdf算法原理图:有几点注意:根节点和叶节点实际是一套规则,并不包含日志数据真正的日志数据在叶节点之下的LogGroup第一层节点,基于假设:具有相同日志事件的日志消息可能具有相同的日志消息长度第二层节点,基于......
  • 安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?
    视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。平台支持国标GB/T28181协议、部标JT808、GA/T1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤......
  • 最小生成树学习笔记
    最小生成树证明最小生成树构成的过程实际上是做\(n-1\)次操作,每一次合并一个点集,直到图中只剩下一个集合为止。要达到的就是让每一次合并的代价之和最小。那么我们实际上可以贪心地选择边权最小的并且能够合并集合的边(Kruskal算法),这个算法的正确性简单来说可以用反证法来证......
  • 2024云栖大会资料精选,《云原生+AI核心技术&最佳实践》PPT全量放送!
    2024云栖大会已圆满落幕。一年一度的云栖大会,已成为云计算和数字经济的风向标。本届云栖大会更加注重AI技术在各行各业的实际应用,让AI技术真正落地,服务于社会各领域。AI时代的到来,向企业底层IT资源的丰富与敏捷提出了更大的挑战。当谈到构建高效、弹性的智能化基础设施时......
  • 首发!米尔全志T536核心板,17串口4CAN口、四核A55
    在智能制造与物联网技术日新月异的今天,一款集高性能、低功耗、高可靠性于一身的工业级核心板成为了推动产业升级的关键力量。米尔电子向市场推出——国产真工业级四核Cortex-A55米尔全志T536核心板,助力国产真工业级工控板快速发展,为工业自动化、工业控制、机器人等领域提供强大的......
  • (二)WPF布局
    <Windowx:Class="WpfTest.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.c......
  • 在 win10 2021 LTSC 上安装配置 wsl2 和 ubuntu
    一、起因因为C盘文件太多,加之程序错误,导致C盘中出现许多无效项,注册列表也出现了很多的错误,因此对计算机系统进行了重装操作,并且不是由本地进行的重装,通过微软的服务器进行的重装。在重装之前,Windows的linux子系统,是完全正常使用的。但是在重装后试图重新安装Linux子系统,就发现......