请保留-> 【原文: https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】
由于GUILite是由C++开发的,将其移植到UEFI下,意味着代码必须用C++来编写。
以下的内容,大部分来自于《UEFI原理与编程》第10章,将需要的代码整合到了我自己的框架中。有些书中没有遇到的小问题,博客中也给了解决办法。
1 C与C++之于UEFI
UEFI中的程序遵循的是C语言的规则,大部分时候应该用模块化的思维方式去理解代码。在日常开发的时候并没有什么问题,何况C语言比C++更适合直接与硬件打交道的场景。不过,遇到稍大点的GUI应用,或者移植遗留的C++代码时,就不得不采用C++了。比如这次的GuiLite的移植工作。
在windows下,开发所用的工具是Visual Studio,编译器cl本身就是支持C++的。因此,我们所要做的工作是让UEFI的入口函数能够“认识”C++的代码。
C++与C的主要区别在于函数名、数组名等,在经过编译后会不同。这是名字修饰的过程,大部分编译原理的书籍中都有描述过。因此,如果直接用C的代码去调用C++的库,会导致链接失败的。
为了支持C++,EDK2在后续的版本中,也逐渐地添加了一些支持。比如在生成的中间文件AutoGen.h中,自动添加了extern “C”,解决了中间文件的名字修饰问题。
我的开发环境是UDK2018+VS2015,在Win10上进行开发的。
2 支持基础的类
基本上进行以下四个步骤,就可以支持C++的类的功能了。
1) 解决名字修饰问题
这个问题比较简单,只需要在C++源文件中,将C语言的头文件用extern “C”包含起来就可以了。如图:
对于老版本EDK2中的AutoGen.h未解决名字修饰问题,在我现在用的这个版本已经接近了,可以忽略掉。
2) 在C++中使用NULL
想要在UEFI的C++代码中使用NULL,需要重新定义:
#undef NULL
#define NULL 0
3) 在C++中使用布尔型
可以在inf文件中修改编译选项来解决:
4) /Zc:wchar_t问题
我的示例代码,会使用StdLib中的函数。编译的时候提示这个错误:
直接在EfiCdefs.h中,将330行的语句注释掉就行了。
经过上述四个步骤,UEFI的代码就可以支持基础的类了。包括类的构造函数和析构函数、派生等,都可以支持。不过,如果需要支持类的全局实例化,还需要做些工作。
3 类的全局实例化
这里我直接借用了《UEFI原理与编程》中的代码。
具体来说,可以从汇编语言观察C++的如何进行全局构建与全局析构的。模仿其流程,在执行实际应用代码的前后,处理全局的类实例。
这种方法比较复杂,具体的可以参考原书的说明。需要注意的是,这是windows平台Visual studio的处理方法,换一个平台或者编译器,代码都不能通用。
这是搭建好的代码框架:
其中,crt0data.cpp来自于上述参考书中的代码,为了表明出处,源文件的名字我也保留了。
至此,框架搭建完毕。至于支持new和delete的内存处理方式,在GUILite中并没有用到,我就不添加了。
百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
文件在 FF RobinPkg/ RobinPkg /Applications/CppMain
3,609 total views, 2 views today
受益匪浅,请教下如果想用gcc编译器得话 linux下怎么支持c++
方式差不多,我没有写出来。具体可以参考《uefi原理与编程的》相关章节