> 文档中心 > 【OpenHarmony】ohos_shared_library默认关闭了异常机制no-exceptions

【OpenHarmony】ohos_shared_library默认关闭了异常机制no-exceptions

文章目录

  • 一、背景
  • 二、探索
    • 1、BUILD.gn
    • 2、usbmgr.gni
    • 3、ohos.gni
    • 4、cxx.gni
    • 5、BUILDCONFIG.gn
  • 三、总结

一、背景

  • 发现usb_manager仓下,usb_service.cpp文件里面,有些地方使用了make_shared方法来创建堆内存。并在后面通过判断指针是否为空,来判断内存是否申请成功,如下:
handler_ = std::make_shared<UsbServerEventHandler>(eventRunner_, pms);if (handler_ == nullptr) {    USB_HILOGE(MODULE_USB_SERVICE, "Init failed due to create handler error");    return false;}
  • 按照我们这篇文章说的 【c/c++】打印uint8_t类型—nothrow—no-exceptions,c++是默认使用异常机制的,所以应该使用try catch来判断make_shared是否成功。
  • 但是当我改造成try catch之后,发现报错了:
error: cannot use 'try' with exceptions disabled    try {    ^1 error generated.
  • 这个错误似曾相识啊,不就是上一篇文章里面提到的同时使用了try catchno-exceptions导致的嘛。所以至此我们明白了,编译usb_service.cpp文件的时候,肯定是禁用了异常机制。ok,下面我们就看一下到底是在哪里加入了no-exceptions

二、探索

1、BUILD.gn

  • 通常来说no-exception这种应该在BUILD.gnconfig里面设置,我们来看下usb_service.cpp文件编译的地方:
import("//base/usb/usb_manager/usbmgr.gni")...ohos_shared_library("usbservice") {  sources = [  ...    "native/src/usb_service.cpp",    ...  ]  configs = [    "${utils_path}:utils_config",    ":usbsrv_private_config",  ]  public_configs = [ ":usbsrv_public_config" ]  ...}
  • 查看其configpublic_config里面都没有no-exception的配置。

2、usbmgr.gni

  • 我们继续向上层找呗,看下usbmgr.gni里面,发现也就是几个变量的声明,并无其他:
import("//build/ohos.gni")usb_manager_path = "//base/usb/usb_manager"usb_manager_part_name = "usb_manager"utils_path = "${usb_manager_path}/utils"

3、ohos.gni

  • 那就继续向上找,看下ohos.gni呗,全都是import,晕。。。,一个个翻一下,看看里面都做了些啥。
...# import cxx base templatesimport("//build/templates/cxx/cxx.gni")...import("//build/templates/common/ohos_templates.gni")# import prebuilt templatesimport("//build/templates/cxx/prebuilt.gni")

4、cxx.gni

  • 其他的我们略过,直接来看看cxx.gni
template("ohos_executable") {...template("ohos_shared_library") {···template("ohos_static_library") {...template("ohos_source_set") {
  • 好亲切啊,这里面不就是我们经常用到的一些玩意吗,并且我们的usb_service.cpp,就是通过ohos_shared_library来编译的。好那我们就详细看下这是咋实现的。
template("ohos_shared_library") {...if (defined(invoker.use_exceptions) && invoker.use_exceptions) {  configs += [ "//build/config/compiler:exceptions" ]  configs -= [ "//build/config/compiler:no_exceptions" ]}...
  • 其他的我不关注,我就是要找no_exceptions是在哪里被加进去的,configs -= [ "//build/config/compiler:no_exceptions" ]这一句和我们有关系,但是他是去掉no_exceptions
  • 并且通过上下文,我们大致能看懂,就是说如果你在用ohos_shared_library的时候,config里面设置了use_exceptions,那么这里就会把exceptions加进去,而把no_exceptions去掉。这样你的代码就能使用异常机制了。
  • 那我们直接搜一下no_exceptions看看它在哪里用了。
    在这里插入图片描述
  • 发现用它的地方还真不多,除了cxx.gni只有BUILDCONFIG.gn用了。

5、BUILDCONFIG.gn

  • ok,看一下BUILDCONFIG.gn文件:
default_compiler_configs = [..."//build/config/compiler:no_exceptions",...]
  • 原来是有个默认的编译配置:
  default_shared_library_configs = default_compiler_configs + [
  • shared library的默认配置是在,全局默认配置基础上进行了修改而来。
set_defaults("shared_library") {  configs = default_shared_library_configs}
  • 然后通过set_defaults方法将默认配置,设置给shared_library类型的目标。set_defaults是gn原生的方法。
  • ok,至此探索完毕。

三、总结

  • 最终我们的结论是ohos_shared_library默认关闭了异常机制no-exceptions
  • 它是通过设置全局的默认编译配置default_compiler_configs,然后各种目标类型根据需要,在全局配置基础上,加上各目标类型自己的配置,生成目标类型所需配置,如default_shared_library_configs
  • 最后在通过set_defaults方法将配置设置到对应目标类型中去。

虫部落快搜