首页 > 编程语言 >在 C# CLR 中学习 C++ 之了解 extern

在 C# CLR 中学习 C++ 之了解 extern

时间:2022-09-02 10:57:38浏览次数:54  
标签:fly C# C++ cpp gc extern include

一:背景

在 CLR 源码中有很多的 externextern "C" 这样的关键词,比如下面这些代码:


extern size_t gc_global_mechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT];

extern DWORD g_dwHandles;

// The single GC heap instance, shared with the VM.
extern IGCHeapInternal* g_theGCHeap;

extern PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntimeFunction, /* out */ SIZE_T * pSize);

extern "C" uint32_t* g_gc_card_table;
extern "C" uint8_t* g_gc_lowest_address;

extern "C"
{
    uint8_t *g_gc_sw_ww_table = nullptr;
    bool g_gc_sw_ww_enabled_for_gc_heap = false;
}

那这些都是什么意思呢? 为了更好的学习 CLR,这些还是要简单了解一下的。

一:extern

1. 变量定义和变量引用

在 C# 中并没有听说过有 extern 这种概念,其实变量可以有两种方式存在。

  1. 变量定义

  2. 变量引用

变量定义概念很简单,定义就得给它分配内存空间,比如下面这样:


#include <iostream>
#include <Windows.h>

int k = 10;
const char* ch = "abcde";

int main()
{
	printf("ch=%d", strlen(ch));
}

接下来看下 变量引用,它其实和 文件引用 以及 C# 的 using 概念相似,即把其他文件中的变量引入到本文件,目的就是为了使用,比如在 Arts 文件下定义了一个 page.cpp 文件,截图如下:

为了能够在 ConsoleApplication3.cpp 中使用 int i ,那怎么办呢? 这时候就需要用 extern 引入了。

因为 VisualStudio 可以帮我们自动链接,所以这里就不需要 #include "page.cpp" 导入,接下来把程序跑起来,就可以观察到程序的结果。

如果不用 extern 导入的话,就会出现编译错误,说 n 是未定义的。

还有一点要注意 extern 是对外部变量的一个引用,它不会生成任何汇编代码。

2. extern "C"

要理解这个关键词,首先要明白 方法符号 的概念,因为 C 和 C++ 在给方法生成符号的逻辑是不一样的,比如同样的一个 fly 函数。


#include <stdio.h>

void fly() {
	printf("hello world");
}

int main()
{
}

在 C 中生成的函数名还是 fly 字样。

可 C++ 不这么认为,它会对 fly 函数名重新编排,比如下面的 ?fly@@YAXXZ

如果你在 C++ 中混用 C 的话,这时候就有理念冲突,那在C++中让某些函数名还是原样生成有办法吗?当然可以了,这就需要使用 extern "C" ,参考如下代码:


// page.cpp
#include <stdio.h>

extern "C"
{
	void fly() {
		printf("hello");
	}
}

void fly2() {
	printf("hello");
}

然后可以在 ConsoleApplication.cpp 中引入进来。


// ConsoleApplication.cpp

#include <iostream>

extern "C" void fly();

extern void fly2();

int main()
{
	fly();

	fly2();

	return 0;
}

好了,本篇就简单说这么多吧,相信再回头看 CLR 中的那些 extern 关键词,你会有一些新的理解。

标签:fly,C#,C++,cpp,gc,extern,include
From: https://www.cnblogs.com/huangxincheng/p/16649028.html

相关文章

  • 使用Torchmetrics快速进行验证指标的计算
    TorchMetrics可以为我们提供一种简单、干净、高效的方式来处理验证指标。TorchMetrics提供了许多现成的指标实现,如Accuracy,Dice,F1Score,Recall,MAE等等,几乎最常见的......
  • SAP Spartacus 项目开发时需要注意的一些常见错误
    SAPSpartacus的工作原理与HybrisAccelerator不同。SAP不建议直接复制Spartacuslibrary的源代码并在源代码级别上进行修改,这会破坏Spartacus的可升级性。正确的......
  • K8s cronjob Usage
    环境:Ubuntu20.04使用minikube创建nodeminikubestart--nodes2-pmultinode-demo创建完成之后使用下面的命令查看kubectlgetnodes#查看创建的nodeminikubes......
  • ROLLFORWARD DATABASE command
    ROLLFORWARDDATABASE commandhttps://www.ibm.com/docs/en/db2/11.1?topic=commands-rollforward-databaseLastUpdated:2022-06-17The ROLLFORWARDDATABASE com......
  • 数据mock
    软件生存周期提出问题(客户)可行性分析(产品经理、经济、社会、法律、技术可行性)需求分析(产品经理绘制原型图)概要设计(时序图、类图等UML)详细设计(接口设计、Ul设计、数......
  • clickhouse安装
    一、版本选择clickhouse对centos版本有要求,全部版本可以这里看https://repo.clickhouse.tech/tgz/不同的linux版本对应哪些可以这里看https://packagecloud.io/app/Al......
  • oracle创建序列
    1创建一个序列,这个是给userLoginlog表用的,所以起了个关联名createsequenceseq_on_userloginincrementby1startwith1nomaxvaluenocyclenocache;2插入数据......
  • ECCV 2022 | MVDG:一种用于域泛化的统一多视图框架
    前言 论文提出了一种新的多视图分布式目标框架,以有效地减少训练和测试阶段的过拟合。具体来说就是,在训练阶段,开发了一种多视图正则化元学习算法,利用多个优化轨迹产生适合......
  • CMAKE 调用交叉编译器(CMAKE使用)
    CMAKE命令使用时需要与CMakeLists.txt在不同的目录下,一般是在CMakeList.txt文档所在的目录下创建一个build文件夹,然后cd到build文件夹,执行cmake..,此时会根据CMakeLists.......
  • 关于ag-grid-vue导出excel表格 进行内容valueFormatter
    最近在写ag-grid-vue的项目,用到了导出Excel功能,但是导出的数据是原始数据,不怎么理想,后来找了点方法进行处理,导出效果很好 <AgGrid...:defaultE......