#pragma package(smart_init)

#pragma package(smart_init)确保已打包的单元按照其依赖关系确定的顺序进行初始化(默认情况下包含在package(包)源文件中。)通常,您将#pragma package用于作为package(包)构建的.cpp文件。简而言之就是按照单元的依赖关系顺序进行初始化,一般用于构建Package(软件包)中

注意:不要在头文件中使用#pragma package(smart_init)。 这样做可能导致编译器错误。

该编译指令影响该编译单元的初始化顺序。 对于单元,初始化按以下顺序进行:

1)根据它们的“uses”依赖性,即,如果unitA依赖于unitB,则必须在unitA之前初始化unitB。

2)链接顺序。

3)单元(unit)内的优先级顺序。

对于常规目标文件(obj文件)(不是作为单元(unit)构建的目标文件),首先根据优先级顺序进行初始化,然后根据链接顺序进行初始化。 更改对象文件的链接顺序将更改全局对象构造函数的调用顺序。

以下示例显示了单元和常规目标文件之间的初始化有何不同。

假设您有三个源文件A,B和C,它们使用#pragma package(smart_init)“智能初始化”,并且具有优先级设置为10、20和30的函数(由#pragma startup的优先级参数定义)。这些函数是根据其优先级值和父源文件命名的,因此名称分别为a10,a20,a30,b10,b20等。这是三个程序A,B和C:

// A.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void A10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A10 10 void A20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A20 20 void A30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup A30 30
// B.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void B10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B10 10 void B20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B20 20 void B30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup B30 30
// C.cpp
#include <stdio.h> #ifdef USE_PACKAGE_INIT
#pragma package(smart_init)
#endif void C10() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C10 10 void C20() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C20 20 void C30() {
printf("%s() ", __FUNCTION__);
}
#pragma startup C30 30

如果按编写的方式并定义了USE_PACKAGE_INIT来构建源文件,则会打印出以下内容:

> A10() A20() A30() B10() B20() B30() C10() C20() C30()

也就是说,优先级被忽略,每个单元一次运行其所有初始化。

如果您在未定义USE_PACKAGE_INIT的情况下构建源文件,则会得到完全不同的结果。 在这种情况下,运行程序时,将输出以下内容:

> A10() B10() C10() A20() B20() C20() A30() B30() C30()

也就是说,使用 startup优先级顺序。

由于这三个都是单元,并且如果A uses B和C,并且链接顺序是A,B,C,则初始化的顺序是:

> B10()B20()B30()C10()C20()C30() A10()A20()A30()

如果以上是目标文件,而不是单元,则顺序为:

> A10()B10()C10()A20()B20()C20()A30()B30()C30()

使用#pragma package(smart_init)的.cpp文件还要求从任意声明#pragma pragma(smart_init)的.cpp文件中到其他目标文件的任何#pragma link引用都必须由一个单元解析。仍然可以通过库解析对非对象文件的#pragma link引用,依此类推。

#pragma package(smart_init, weak)

#pragma package(smart_init,weak)指令会影响对象文件在包的.bpi和.bpl文件中的存储方式。 如果#pragma package(smart_init,weak)出现在单元文件中,则编译器将在可能的情况下从BPL中忽略该单元,并在另一个应用程序或程序包需要时创建该单元的未打包的本地副本。 使用此伪指令编译的单元被称为“弱包装”。

#pragma package(smart_init,weak)用于消除可能依赖于同一外部库的程序包之间的冲突。

包含#pragma package(smart_init,weak)指令的单元文件不得具有全局变量。

#pragma link

语法:

  

#pragma link "[path]modulename[.ext]"

#pragma link指令指示链接程序将指定文件链接到可执行文件中。

使用path参数指定目录。 缺省情况下,链接器在本地目录和链接器的-L选项指定的任何路径中搜索模块名称。

只要您使用默认文件类型,就不要指定modulename的文件扩展名(.ext)。 链接器为modulename的文件扩展名(.ext)假定以下默认值:

  • .obj extension for BCC32
  • .o extension for Clang-enhanced C++ compilers

因此,如果省略.ext,则会根据您当前的目标平台自动使用正确的扩展名。

#pragma directive的更多相关文章

  1. #pragma Directive in C/C++

    The #pragma is complier specified. for example, the code below does not work in gcc. #pragma startup ...

  2. 重新梳理HTML基础知识

    缘起 HTML(HyperText Markup Language超文本标记语言)是用于构建web页面的标记语言和通用标准.它并不是一项新的发明,因为超文本(具有超链接的文本)和标记语言(用于电子文档 ...

  3. C中的预编译宏定义

     可以用宏判断是否为ARC环境 #if _has_feature(objc_arc) #else //MRC #endif C中的预编译宏定义 -- 作者: infobillows 来源:网络 在将一 ...

  4. How do I place a group of functions or variables in a specific section?

    http://supp.iar.com/Support/?Note=27498 EWARM v5.xx (and newer) The placement of a few functions in ...

  5. RFC 2616

    Network Working Group R. Fielding Request for Comments: 2616 UC Irvine Obsoletes: 2068 J. Gettys Cat ...

  6. 基于NodeJs的网页爬虫的构建(一)

    好久没写博客了,这段时间已经忙成狗,半年时间就这么没了,必须得做一下总结否则白忙.接下去可能会有一系列的总结,都是关于定向爬虫(干了好几个月后才知道这个名词)的构建方法,实现平台是Node.JS. 背 ...

  7. scanf()常犯错误

    ------------------------------------------------------------------------ <> 本意:接收字符串. 写成代码:voi ...

  8. RFC2616-HTTP1.1-Header Field Definitions(头字段规定部分—单词注释版)

    part of Hypertext Transfer Protocol -- HTTP/1.1RFC 2616 Fielding, et al. 14 Header Field Definitions ...

  9. HTML5 Differences from HTML4

    Abstract "HTML5 Differences from HTML4" describes the differences of the HTML5 specificati ...

  10. C预编译, 预处理, C/C++头文件, 编译控制,

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

随机推荐

  1. Azure Artifacts--全平台的程序包管理仓库(支持nuget)

    写在前面 大部分一定规模的团队都有搭建私有nuget的需求:例如: MyGet BaGet 而我们使用的Azure DevOps 平台本身就提供了Artifacts, Artifacts不单只支持nu ...

  2. Gateway服务网关 (入门到使用)

    Gateway服务网关 Gateway也要作为微服务注册到nacos中 Zuul也是网关但比较老是一种阻塞式编程:Spring Cloud Gateway 是 Spring Cloud 的一个全新项目 ...

  3. 翻译《threejsfundamentals》离屏渲染+web-worker一篇

    Three.js OffscreenCanvas    OffscreenCanvas是一种相对较新的浏览器功能,目前仅在Chrome中可用,但显然也即将适用于其他浏览器. OffscreenCanv ...

  4. CSP-J初赛知识点

    就要初赛了,知识点还没怎么看,今天花一个小时来整理一下,希望大家在初赛中有个好成绩## 计算机常识IT : Information Technology 信息技术代别         年代       ...

  5. React中组件之间是如何通信的 react的组件通信方式有哪些

    一.是什么 通信指的是发送者通过某种媒体 以某种格式来传递信息 到收信者以达到某个目的,广义上,任何信息的传递都是通信 二.如何通信? 组件传递的方式有很多种,根据传送者和接收者可以分为如下: 父组件 ...

  6. 手把手教你为基于Netty的IM生成自签名SSL/TLS证书

    1.引言 对于IM聊天应用来说,为了提升安全性,对聊天消息加密是常规操作. 众所周之,Netty是高性能的Java NIO网络通信框架,因而用Netty来写IM是再正常不过了.网上关于为Netty生成 ...

  7. GitHub 入门 与 2023年2月18日10:29:02

    用 GitHub 有一段时间了,之前一直用来做 Hexo 的服务器,直到前阵子搞 GitHub Action 因为命令不熟,把 GitHub 上的源码强制拉到本地把本地的 Hexo 搞崩了,博客源码都 ...

  8. 【雅礼联考DAY02】Revolution

    #include<cstdio> #include<queue> using namespace std; const int N = 210 , M = 210000 , I ...

  9. CentOS7一键安装RPM版LNMP(NGINX+PHP+MySQL)环境

    转载:简书 CentOS7一键安装RPM版LNMP(NGINX+PHP+MySQL)环境 - 简书 (jianshu.com) (需要配置nginx.conf文件) 转载:csdn (35条消息) V ...

  10. .Net 获取URL中指定参数值

    有时候我们调用第三方接口,返回的并不是完整的链接带参数,而我们只需要获取指定的一些参数 例如:code=200&msg=success&timestamp=1657539&no ...