这里写目录标题

  • 1. Go 与 C 语言的互操作
    • 1.1. Go 调用 C 代码的原理
    • 1.2. 在 Go 中使用 C 语言的类型
      • 1.2.1. 原生类型
        • 1.2.1.1. 数值类型
        • 1.2.1.2. 指针类型
        • 1.2.1.3. 字符串类型
        • 1.2.1.4. 数组类型
        • 1.2.1.5. 自定义类型
          • 1.2.1.5.1. 枚举(enum)
          • 1.2.1.5.2. 结构体(struct)
          • 1.2.1.5.3. 联合体(union)
          • 1.2.1.5.4. typedef
    • 1.3. Go 中访问 C 的变量和函数
    • 1.4. C 中使用 Go 函数
    • 1.5. 其他

1. Go 与 C 语言的互操作

Go 有强烈的 C 背景, 除了语法具有继承性外, 其设计者以及其设计目标都与 C 语言有着千丝万缕的联系。在 Go 与 C 语言互操作 (Interoperability) 方面, Go 更是提供了强大的支持。尤其是在 Go 中使用 C, 你甚至可以直接在 Go 源文件中编写 C 代码, 这是其他语言所无法望其项背的。

在如下一些场景中, 可能会涉及到 Go 与 C 的互操作:

  1. 提升局部代码性能时, 用 C 替换一些 Go 代码。C 之于 Go, 好比汇编之于 C。
  2. 嫌 Go 内存 GC 性能不足, 自己手动管理应用内存。
  3. 实现一些库的 Go Wrapper。比如 Oracle 提供的 C 版本 OCI, 但 Oracle 并未提供 Go 版本的以及连接 DB 的协议细节, 因此只能通过包装 C OCI 版本的方式以提供 Go 开发者使用。
  4. Go 导出函数供 C 开发者使用(目前这种需求应该很少见)。
  5. Maybe more…

1.1. Go 调用 C 代码的原理

下面是一个短小的例子:

package main// #include <stdio.h>
// #include <stdlib.h>
/*
void print(char *str) {printf("%s\n", str);
}
*/
import "C"import "unsafe"func main() {s := "Hello Cgo"cs := C.CString(s)C.print(cs)C.free(unsafe.Pointer(cs))
}

与 "正常"Go 代码相比, 上述代码有几处 “特殊” 的地方:

  1. 在开头的注释中出现了 C 头文件的 include 字样
  2. 在注释中定义了 C 函数 print
  3. import 的一个名为 C 的 “包”
  4. 在 main 函数中居然调用了上述的那个 C 函数 - print

没错, 这就是在 Go 源码中调用 C 代码的步骤, 可以看出我们可直接在 Go 源码文件中编写 C 代码。

首先, Go 源码文件中的 C 代码是需要用注释包裹的, 就像上面的 include 头文件以及 print 函数定义;
其次, import “C” 这个语句是必须的, 而且其与上面的 C 代码之间不能用空行分隔, 必须紧密相连。这里的 “C” 不是包名, 而是一种类似名字空间的概念, 或可以理解为伪包, C 语言所有语法元素均在该伪包下面;
最后, 访问 C 语法元素时都要在其前面加上伪包前缀, 比如 C.uint 和上面代码中的 C.print、C.free 等。

我们如何来编译这个 go 源文件呢? 其实与 "正常"Go 源文件没啥区别, 依旧可以直接通过 go build 或 go run 来编译和执行。但实际编译过程中, go 调用了名为 cgo 的工具, cgo 会识别和读取 Go 源文件中的 C 元素, 并将其提取后交给 C 编译器编译, 最后与 Go 源码编译后的目标文件链接成一个可执行程序。这样我们就不难理解为何 Go 源文件中的 C 代码要用注释包裹了, 这些特殊的语法都是可以被 Cgo 识别并使用的。

1.2. 在 Go 中使用 C 语言的类型

1.2.1. 原生类型

1.2.1.1. 数值类型

在 Go 中可以用如下方式访问 C 原生的数值类型:

C.char,
C.schar (signed char),
C.uchar (unsigned char),
C.short,
C.ushort (unsigned short),
C.int, C.uint (unsigned int),
C.long,
C.ulong (unsigned long),
C.longlong (long long),
C.ulonglong (unsigned long long),
C.float,
C.double

Go 的数值类型与 C 中的数值类型不是一一对应的。因此在使用对方类型变量时少不了显式转型操作, 如 Go doc 中的这个例子:

func Random() int {return int(C.random())//C.long -> Go 的 int
}func Seed(i int) {C.srandom(C.uint(i))//Go 的 uint -> C 的 uint
}

1.2.1.2. 指针类型

原生数值类型的指针类型可按 Go 语法在类型前面加上 *, 比如 var p *C.int。而 void * 比较特殊, 用 Go 中的 unsafe.Pointer 表示。任何类型的指针值都可以转换为 unsafe.Pointer 类型, 而 unsafe.Pointer 类型值也可以转换为任意类型的指针值。unsafe.Pointer 还可以与 uintptr 这个类型做相互转换。由于 unsafe.Pointer 的指针类型无法做算术操作, 转换为 uintptr 后可进行算术操作。

1.2.1.3. 字符串类型

C 语言中并不存在正规的字符串类型, 在 C 中用带结尾’\0’的字符数组来表示字符串; 而在 Go 中, string 类型是原生类型, 因此在两种语言互操作是势必要做字符串类型的转换。

通过 C.CString 函数, 我们可以将 Go 的 string 类型转换为 C 的 “字符串” 类型, 再传给 C 函数使用。就如我们在本文开篇例子中使用的那样:

s := "Hello Cgo\n"
cs := C.CString(s)
C.print(cs)

不过这样转型后所得到的 C 字符串 cs 并不能由 Go 的 gc 所管理, 我们必须手动释放 cs 所占用的内存, 这就是为何例子中最后调用 C.free 释放掉 cs 的原因。在 C 内部分配的内存, Go 中的 GC 是无法感知到的, 因此要记着释放。

通过 C.GoString 可将 C 的字符串 (*C.char) 转换为 Go 的 string 类型, 例如:

// #include <stdio.h>
// #include <stdlib.h>
// char *foo = "hellofoo";
import "C"import "fmt"func main() {
… …fmt.Printf("%s\n", C.GoString(C.foo))
}

1.2.1.4. 数组类型

C 语言中的数组与 Go 语言中的数组差异较大, 后者是值类型, 而前者与 C 中的指针大部分场合都可以随意转换。目前似乎无法直接显式的在两者之间进行转型, 官方文档也没有说明。但我们可以通过编写转换函数, 将 C 的数组转换为 Go 的 Slice(由于 Go 中数组是值类型, 其大小是静态的, 转换为 Slice 更为通用一些), 下面是一个整型数组转换的例子:

// int cArray[] = {1, 2, 3, 4, 5, 6, 7};func CArrayToGoArray(cArray unsafe.Pointer, size int) (goArray []int) {p := uintptr(cArray)for i :=0; i < size; i++ {j := *(*int)(unsafe.Pointer(p))goArray = append(goArray, j)p += unsafe.Sizeof(j)}return
}func main() {… …goArray := CArrayToGoArray(unsafe.Pointer(&C.cArray[0]), 7)fmt.Println(goArray)
}

执行结果输出: [1 2 3 4 5 6 7]

这里要注意的是: Go 编译器并不能将 C 的 cArray 自动转换为数组的地址, 所以不能像在 C 中使用数组那样将数组变量直接传递给函数, 而是将数组第一个元素的地址传递给函数。

1.2.1.5. 自定义类型

除了原生类型外, 我们还可以访问 C 中的自定义类型。

1.2.1.5.1. 枚举(enum)
// enum color {
//    RED,
//    BLUE,
//    YELLOW
// };var e, f, g C.enum_color = C.RED, C.BLUE, C.YELLOW
fmt.Println(e, f, g)

输出: 0 1 2

对于具名的 C 枚举类型, 我们可以通过 C.enum_xx 来访问该类型。如果是匿名枚举, 则似乎只能访问其字段了。

1.2.1.5.2. 结构体(struct)
// struct employee {
//     char *id;
//     int  age;
// };id := C.CString("1247")
var employee C.struct_employee = C.struct_employee{id, 21}
fmt.Println(C.GoString(employee.id))
fmt.Println(employee.age)
C.free(unsafe.Pointer(id))

输出:

1247
21

和 enum 类似, 我们可以通过 C.struct_xx 来访问 C 中定义的结构体类型。

1.2.1.5.3. 联合体(union)

这里我试图用与访问 struct 相同的方法来访问一个 C 的 union:

// #include <stdio.h>
// union bar {
//        char   c;
//        int    i;
//        double d;
// };
import "C"func main() {var b *C.union_bar = new(C.union_bar)b.c = 4fmt.Println(b)
}

不过编译时, go 却报错: b.c undefined (type *[8]byte has no field or method c)。从报错的信息来看, Go 对待 union 与其他类型不同, 似乎将 union 当成[N]byte 来对待, 其中 N 为 union 中最大字段的 size(圆整后的), 因此我们可以按如下方式处理 C.union_bar:

func main() {var b *C.union_bar = new(C.union_bar)b[0] = 13b[1] = 17fmt.Println(b)
}

输出: &[13 17 0 0 0 0 0 0]

1.2.1.5.4. typedef

在 Go 中访问使用用 typedef 定义的别名类型时, 其访问方式与原实际类型访问方式相同。如:

// typedef int myint;var a C.myint = 5
fmt.Println(a)// typedef struct employee myemployee;var m C.struct_myemployee

从例子中可以看出, 对原生类型的别名, 直接访问这个新类型名即可。而对于复合类型的别名, 需要根据原复合类型的访问方式对新别名进行访问, 比如 myemployee 实际类型为 struct, 那么使用 myemployee 时也要加上 struct_ 前缀。

1.3. Go 中访问 C 的变量和函数

实际上上面的例子中我们已经演示了在 Go 中是如何访问 C 的变量和函数的, 一般方法就是加上 C 前缀即可, 对于 C 标准库中的函数尤其是这样。不过虽然我们可以在 Go 源码文件中直接定义 C 变量和 C 函数, 但从代码结构上来讲, 大量的在 Go 源码中编写 C 代码似乎不是那么 “专业”。那如何将 C 函数和变量定义从 Go 源码中分离出去单独定义呢? 我们很容易想到将 C 的代码以共享库的形式提供给 Go 源码。

Cgo 提供了 #cgo 指示符可以指定 Go 源码在编译后与哪些共享库进行链接。我们来看一下例子:

package main// #cgo LDFLAGS: -L ./ -lfoo
// #include <stdio.h>
// #include <stdlib.h>
// #include "foo.h"
import "C"
import "fmt"func main() {fmt.Println(C.count)C.foo()
}

我们看到上面例子中通过 #cgo 指示符告诉 go 编译器链接当前目录下的 libfoo 共享库。C.count 变量和 C.foo 函数的定义都在 libfoo 共享库中。我们来创建这个共享库:

// foo.hint count;
void foo();//foo.c
#include "foo.h"int count = 6;
void foo() {printf("I am foo!\n");
}
$> gcc -c foo.c
$> ar rv libfoo.a foo.o

我们首先创建一个静态共享库 libfoo.a, 不过在编译 Go 源文件时我们遇到了问题:

$> go build foo.go
# command-line-arguments
/tmp/go-build565913544/command-line-arguments.a(foo.cgo2.)(.text): foo: not defined
foo(0): not defined

提示 foo 函数未定义。通过 - x 选项打印出具体的编译细节, 也未找出问题所在。不过在 Go 的问题列表中我发现了一个 issue(http://code.google.com/p/go/issues/detail?id=3755), 上面提到了目前 Go 的版本不支持链接静态共享库。

那我们来创建一个动态共享库试试:

$> gcc -c foo.c
$> gcc -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o

再编译 foo.go, 的确能够成功。执行 foo。

$> go build foo.go && go
6
I am foo!

还有一点值得注意, 那就是 Go 支持多返回值, 而 C 中并没不支持。因此当将 C 函数用在多返回值的调用中时, C 的 errno 将作为 err 返回值返回, 下面是个例子:

package main// #include <stdlib.h>
// #include <stdio.h>
// #include <errno.h>
// int foo(int i) {
//    errno = 0;
//    if (i > 5) {
//        errno = 8;
//        return i – 5;
//    } else {
//        return i;
//    }
//}
import "C"
import "fmt"func main() {i, err := C.foo(C.int(8))if err != nil {fmt.Println(err)} else {fmt.Println(i)}
}
$> go run foo.go
exec format error

errno 为 8, 其含义在 errno.h 中可以找到:

#define ENOEXEC      8  /* Exec format error */

的确是 “exec format error”。

1.4. C 中使用 Go 函数

与在 Go 中使用 C 源码相比, 在 C 中使用 Go 函数的场合较少。在 Go 中, 可以使用 “export + 函数名” 来导出 Go 函数为 C 所使用, 看一个简单例子:

package main/*
#include <stdio.h>extern void GoExportedFunc();void bar() {printf("I am bar!\n");GoExportedFunc();
}
*/
import "C"import "fmt"//export GoExportedFunc
func GoExportedFunc() {fmt.Println("I am a GoExportedFunc!")
}func main() {C.bar()
}

不过当我们编译该 Go 文件时, 我们得到了如下错误信息:

# command-line-arguments
/tmp/go-build163255970/command-line-arguments/_obj/bar.cgo2.o: In function `bar':
./bar.go:7: multiple definition of `bar'
/tmp/go-build163255970/command-line-arguments/_obj/_cgo_export.o:/home/tonybai/test/go/bar.go:7: first defined here
collect2: ld returned 1 exit status

代码似乎没有任何问题, 但就是无法通过编译, 总是提示 “多重定义”。翻看 Cgo 的文档, 找到了些端倪。原来

There is a limitation: if your program uses any //export directives, then the C code in the comment may only include declarations (extern int f();), not definitions (int f() { return 1; }).

似乎是 // extern int f()//export f 不能放在一个 Go 源文件中。我们把 bar.go 拆分成 bar1.gobar2.go 两个文件:

// bar1.gopackage main/*
#include <stdio.h>extern void GoExportedFunc();void bar() {printf("I am bar!\n");GoExportedFunc();
}
*/
import "C"func main() {C.bar()
}// bar2.gopackage mainimport "C"
import "fmt"//export GoExportedFunc
func GoExportedFunc() {fmt.Println("I am a GoExportedFunc!")
}

编译执行:

$> go build -o bar bar1.go bar2.go
$> bar
I am bar!
I am a GoExportedFunc!

个人觉得目前 Go 对于导出函数供 C 使用的功能还十分有限, 两种语言的调用约定不同, 类型无法一一对应以及 Go 中类似 Gc 这样的高级功能让导出 Go 函数这一功能难于完美实现, 导出的函数依旧无法完全脱离 Go 的环境, 因此实用性似乎有折扣。

1.5. 其他

虽然 Go 提供了强大的与 C 互操作的功能, 但目前依旧不完善, 比如不支持在 Go 中直接调用可变个数参数的函数(issue975), 如 printf(因此, 文档中多用 fputs)。

这里的建议是: 尽量缩小 Go 与 C 间互操作范围。

什么意思呢? 如果你在 Go 中使用 C 代码时, 那么尽量在 C 代码中调用 C 函数。Go 只使用你封装好的一个 C 函数最好。不要像下面代码这样:

C.fputs()
C.atoi(..)
C.malloc(..)

而是将这些 C 函数调用封装到一个 C 函数中, Go 只知道这个 C 函数即可。

C.foo(..)

相反, 在 C 中使用 Go 导出的函数也是一样。

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 封装作用实现含义

    我要看电视&#xff0c;只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗?制造厂家为了方便我们使用电视&#xff0c;把复杂的内部细节全部封装起来&#xff0c;只给我们暴露简单的接口&#xff0c;比如&#xff1a;电源开关。具体内部是怎…...

    2024/4/18 17:31:26
  2. Taro 正式发布 3.4 版本: 全面支持 Preact Vue 3.2

    距 Taro v3.4 beta 版本的发布已有一段时间&#xff0c;期间我们完善了对 Preact 和 Vue3 的支持&#xff0c;加入了一些有趣的特性&#xff0c;更是对 H5 作了大幅度的优化与调整&#xff0c;并于近期发布了 v3.4 的正式版本。 上月我们还推出了支持开发鸿蒙应用的 v3.5.0 can…...

    2024/4/14 11:45:45
  3. Redis订阅系统

    Redis发布订阅 订阅/发布消息图&#xff1a;...

    2024/4/14 11:45:25
  4. Vulnhub-shenron-1:神龙1靶机渗透攻略

    下载地址&#xff1a;http://www.vulnhub.com/entry/shenron-1,630/ 虚拟化环境virtualbox 目标&#xff1a;获取两个flag ​ 信息收集 nmap扫描 nmap -sC -sV 192.168.210.181 发现80http &#xff0c;22ssh 网站信息收集 可以看到是一个apache的默认页 ​ 扫描一下后…...

    2024/4/7 5:34:26
  5. 用户规模增长几近停滞,2022年应用下载增长需更多渠道

    当互联网人口红利衰减&#xff0c;对用户的争夺&#xff0c;让各应用市场竞争加速&#xff0c;应用公司的「内卷」、研发成本的飙升&#xff0c;都是为了在当下的存量环境中抢得一席之地。 有大佬用VUCA一词形容当下的时代特性&#xff0c;即Volatility(易变性)、Uncertainty(…...

    2024/4/14 11:45:50
  6. JMeter的基本使用

    目录 一、下载JMeter 二、JMeter界面设置 三、新建线程组(Thread Group) 四、新建HTTP请求(HTTP Request) 五、添加信息头管理器(HTTP Header Manager) ​六、创建结果视图(Views Results Tree) 七、运行查看结果 一、下载JMeter 下载地址&#xff1a;Apache JMeter - …...

    2024/4/18 0:45:53
  7. 特殊excel表格导出模板

    1、代码 package com.li.zzh.fileUtils;import java.io.BufferedOutputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;import javax.servlet.http.H…...

    2024/4/17 2:31:23
  8. 部署web项目在腾讯云当中

    一、首先需要去腾讯云 购买一个云服务器&#xff0c;个人可以免费领取一个十五天的体验版. https://cloud.tencent.com/act/free 二、在自己电脑点击开始菜单-> Run&#xff0c;输入"mstsc"命令&#xff0c;即可打开远程桌面连接对话框。 在输入框中输入腾讯云服…...

    2024/4/14 11:45:35
  9. 4.1跳表

    零 跳表介绍 emsp;emsp;emsp;emsp;跳表底层是一个链表。这个链表是按大小顺序排列的。 emsp;emsp;emsp;emsp;然后在底层数据链表上建N层索引&#xff0c;如图所示&#xff1a; 0------------->5 | | 0------------->5 …...

    2024/4/19 9:08:55
  10. C盘满了怎么解决

    总是无故爆满涨红的C盘可谓是电脑“神秘”现象之一&#xff0c;明明只是办公、学习专用却有一堆看不懂的文件侵占C盘空间。C盘状态不佳将严重影响电脑系统的运行&#xff0c;伴随一系列卡顿闪退让人瞬间emo&#xff0c;又不想重装更不想重买&#xff0c;驱动人生教你如何轻松解…...

    2024/4/14 11:45:40
  11. 电路图里面的NS是什么意思

    MPS官方的DCDC芯片电路在线设计软件 NS表示NO STUFF 0欧是方便调试&#xff0c;实际设计无需使用。...

    2024/4/14 11:45:10
  12. Spark CASE WHEN 写法案例

    一、前言 用过大数据的同事都熟悉hive和Spark&#xff0c;两者的语法是一样的&#xff0c;但是Spark的速度要比Hive快得多。今天才写一个Spark的大数据报表的时候&#xff0c;遇到一个group by结合Case When的语法问题&#xff0c;现将问题的详细经过记录下来&#xff0c;希望…...

    2024/4/14 11:45:20
  13. SECOND 阅读

    SECOND: Sparsely Embedded Convolutional Detection Abstract 问题:推理速度慢和方向估计性能低。 我们研究了用于此类网络的改进稀疏卷积方法引入了一种新形式的角度损失回归来提高方向估计性能一种新的数据增强方法,可以提高收敛速度和性能Introduction 为基于 LiDAR 的…...

    2024/4/15 6:30:07
  14. 整数反转(LeetCode)

    解题思路&#xff1a;看到本题&#xff0c;要求进行整数反转&#xff0c;第一感觉是先转成字符串&#xff0c;然后进行反转&#xff0c;为了防止大量的写charAt()&#xff0c;我又将字符串转成了char数组&#xff0c;去除x0的情况&#xff0c;直接返回0&#xff0c;然后要注意的…...

    2024/4/18 1:36:13
  15. 攻防世界--mail

    尝试登陆admin给出提示可知存在admin账号 尝试注入显示只能是数字和字母&#xff0c;先注册进去&#xff0c;给出提示 通过扫描目录可以发现/flag目录 查看session 要更改session就需要secret_key 经测试&#xff0c;发现在注册时邮箱位置存在sql注入(添加单撇号报错) 使用…...

    2024/4/15 6:29:12
  16. 分布式事务解决方案

    前言 最近在学习分布式事务解决方案&#xff0c;所以就想抽个时间查阅资料&#xff0c;自己做一个总结。如果你去自己去网上搜寻的话&#xff0c;大家提供的方案都差不多&#xff0c;这个当然是没有固定方案&#xff0c;还是要根据具体的业务场景来确定的。&#xff08;若文章有…...

    2024/4/19 12:47:37
  17. ROS操作系统安装步骤

    配置 Ubuntu 仓库 打开系统设置里的软件更新&#xff0c;配置 Ubuntu 仓库&#xff0c;勾选 “restricted”&#xff0c;”universe” 和 “multiverse” 等选项 设置 sources.list sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main&q…...

    2024/4/14 11:45:25
  18. 【elasticsearch源码恢复流程】es 7.7

    副本分片请求流程&#xff0c;函数入口&#xff1a;IndicesClusterStateService.createOrUpdateShards org.elasticsearch.indices.cluster.IndicesClusterStateService private void createOrUpdateShards(final ClusterState state) {RoutingNode localRoutingNode state.g…...

    2024/4/20 12:13:37
  19. 【福利帖】7日玩转ESP32——(第1日) Hello World

    文章目录一、ESP32-C3开发板准备二、安装Visual Studio Code三、安装扩展四、配置ESP-IDF 插件五、创建工程六、配置工程6.1 选择目标芯片6.2 项目配置七、编译工程八、固件下载九、今日作业十、参考答案十一、打卡~一、ESP32-C3开发板准备 ESP32-C3 是一款安全、低功耗、低成…...

    2024/4/14 11:46:17
  20. Python多进程多线程多协程

    前言 自己找的一个B站的Python多进程多线程多协程的视频&#xff08;见参考第二条&#xff09;&#xff0c;时间不长&#xff0c;但是感觉讲的还不错&#xff0c;这篇文章也就是个简单的笔记。 怎样选择多进程、多线程、多协程 CPU密集型、IO密集型计算 多进程、多线程、多…...

    2024/4/15 13:27:59

最新文章

  1. 最新优质电商API接口,附带教程【多语言环境高并发】

    给大家更新一波24年一月份的新接口吧。 01 接口信息 线路推荐: 多仓&#xff1a; 1.春盈&#xff1a; https://wds.ecsxs.com/230989.json 2.无意&#xff1a; http://www.wya6.cn/tv/yc.json 3.主流电商平台API数据采集 单仓&#xff1a; 1.饭太硬&#xff1a; http:/…...

    2024/5/6 14:25:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/6 9:38:23
  3. 【LeetCode热题100】【二叉树】二叉搜索树中第K小的元素

    题目链接&#xff1a;230. 二叉搜索树中第K小的元素 - 力扣&#xff08;LeetCode&#xff09; 二次搜索树的中序遍历就是从小到大排序 class Solution { public:vector<int> nums;void inOrder(TreeNode *root) {if (root nullptr)return;inOrder(root->left);nums…...

    2024/5/4 4:54:17
  4. audio_video_img图片音视频异步可视化加载

    最近在做即时消息&#xff0c;消息类型除了文字还有音频、视频、图片展示&#xff0c;如果消息很多&#xff0c;在切换聊天框时&#xff0c;会有明显卡顿&#xff0c;后续做了懒加载&#xff0c;方案是只加载用户能看到的资源&#xff0c;看不到的先不加载&#xff1b; LazyAud…...

    2024/5/6 12:26:53
  5. Linux中的shell脚本之流程控制循环遍历

    3 条件判断 4 流程控制语句 1&#xff09;if 语句 案例&#xff0c;用户输入用户名和密码&#xff0c;判断用户名是否是admin,密码是否是123,如果正确&#xff0c;则显示登录成功 首先我创建了shell文件&#xff0c;touch getpawer 其中getpawer 是我自己命的名 #!/bin/bas…...

    2024/5/5 8:44:49
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/6 9:21:00
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57