一:背景

在 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 关键词,你会有一些新的理解。

最新文章

  1. 用C#实现封装
  2. 我开发 wangEditor-mobile 的故事
  3. mvn install
  4. ArcGIS Engine开发之旅02--ArcGIS Engine中的类库
  5. 【Android - MD】之CardView的使用
  6. C语言位运算
  7. NSThread 、NSRunLoop 和 Dispatch Queue
  8. 转:jquery的live和on
  9. poj_2104: K-th Number 【主席树】
  10. mysql实现高可用架构之MHA
  11. AI应用开发实战
  12. 微信小程序 swiper轮播 自定义indicator-dots样式
  13. leetcode — search-insert-position
  14. Jenkins不同job之间传递参数
  15. Python数字(Number)
  16. Eclipse直接打开类文件/文件夹所在的本地目录
  17. Pandas的concat方法
  18. 【转】HttpServletRequestWrapper 实现xss注入
  19. java-servlet的url-pattern匹配规则详细描述
  20. ajax跨域终极解决办法!

热门文章

  1. C语言学习之我见-strcat()字符拼接函数(有缺陷)
  2. MySQL-4-DDL
  3. java程序使用ssl证书连接mysql
  4. python这不是有手就行?——python音频处理基础知识
  5. NC13328 倒水
  6. 零基础学Java(3)运算符
  7. CF1042E Vasya and Magic Matrix 题解
  8. 算法竞赛进阶指南 0x43 线段树
  9. 安卓系统使用USB转串口
  10. ESP8266 使用 DRV8833驱动板驱动N20电机