网络知识 娱乐 【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 templates
import("//build/templates/cxx/cxx.gni")
...
import("//build/templates/common/ohos_templates.gni")

# import prebuilt templates
import("//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方法将配置设置到对应目标类型中去。