我怎么觉得 Java 的 JNI 比 Go 的 CGO 要好呢?

2022-06-12 23:45:57 +08:00
 thewiredguy
6765 次点击
所在节点    Go 编程语言
47 条回复
learningman
2022-06-12 23:49:59 +08:00
那你总得给个理由吧
thewiredguy
2022-06-13 00:03:19 +08:00
thewiredguy
2022-06-13 00:06:33 +08:00
比方说我用 go 调用 C++,我不想用 pkg-config ,我甚至想要把 C++ 的 .so 嵌入到我最后生成的 executable binary 里,有没有一种方式?别说用 Docker 容器什么的。
SMGdcAt4kPPQ
2022-06-13 00:25:56 +08:00
P/Invoke 请求一战
Buges
2022-06-13 00:36:25 +08:00
so 是动态库啊,一般是不能嵌入的, 虽然有一些魔改的 trick 能从内存中加载动态库,但那绝对不是正常做法。
正常来说你想要静态链接那就去构建静态链接库。
lysS
2022-06-13 00:42:21 +08:00
动态库是单独的文件,你需要的是静态库,本质就是 cgo 绑定 C 。
。。但是这些和垃圾回收有什么关系呢?
SMGdcAt4kPPQ
2022-06-13 00:49:29 +08:00
Suddoo
2022-06-13 01:49:53 +08:00
可以关注一下 巴拿马项目 https://github.com/openjdk/panama-foreign
akaHenry
2022-06-13 02:47:57 +08:00
你的感觉没错.

go 的 cgo, 本来就是个半残. 不建议使用. (早期 uber 等大量依赖 cgo 的, 应该都苦不堪言)

用到 cgo 的场景, 其实应该换语言了. 用 rust/c/c++ 配合 FFI 更合适. (微服务场景, 都是 RPC 抹平 业务单元差异)

不要被单一语言锁死. 适合谁, 谁上.

多学一门语言, 拓宽解决问题的思路.

最坏的就是 all-in-one 思想, 东施效颦, 各种捉急.
nmap
2022-06-13 09:39:31 +08:00
@orzglory #9 一定要用 go 调 c++的话,最佳实践是什么?
Kasumi20
2022-06-13 10:21:28 +08:00
都不如 Rust
cccjh
2022-06-13 10:22:52 +08:00
公司同样的业务,封装底下自研的时序库的动态链接库,
早期 java 调用 jni ,后面改 jna ,
我后面又用 go 去弄 cgo ,
最后我又改成了 python 的 ctypes ,python 最终使用的上层用协程加 ctypes 接口处用多进程
这些全是我一个人弄的,其中整个体验下来,cgo 的体验是最差的,当你想用协程去调 cgo 时,结果可想而知。
akaHenry
2022-06-13 10:24:36 +08:00
@nmap


1. 如果是 Server 端, 可以通过 微服务 RPC(如 gRPC) / Restful API / Websoket 方式来调用. 避免侵入性. 把 C++ 改造成一个独立的服务. 暴露 RPC/Rest API 给 Go 调用. 即可以绕过 cgo.
2. 如果是 client 端, 如果用 Go 写 Client, 这本身已经是邪路. 那只能 cgo. 当然, 如果是 Desktop 桌面版的 app. 也可以同上, 把 桌面版 app 改造成 client/server 模型, 中间变成 proxy, 依然可以走 RPC/Rest API 方式调用.
cxytz01
2022-06-13 10:31:14 +08:00
@orzglory 请问 FFI 是什么?搜索不到。
akaHenry
2022-06-13 10:34:55 +08:00
@cxytz01

github.com/hhstore/blog/issues/242
github.com/hhstore/blog/issues/355

可以参考我这 2 篇博客, 关于 FFI 的内容.

https://en.wikipedia.org/wiki/Foreign_function_interface


FFI 是通用的跨语言调用规范. 主流语言基本都兼容 C ABI.

所以, 都可以通过 C ABI 方式来跨语言通信.
hhaobao
2022-06-13 10:50:29 +08:00
所以到底 cgo 有啥问题? 能具体描述一下吗?
@orzglory
@cccjh
thewiredguy
2022-06-13 11:00:47 +08:00
@lysS JNI 是 Java Native Interface ,不是垃圾回收
janxin
2022-06-13 11:01:02 +08:00
@orzglory 于是现在 uber 换 zig 做 cgo 后端了 233333

CGO 确实体验式最差的,并且尼玛死活没计划改...

不过你说的这个问题倒不是什么比较大的问题,想内嵌不过是 dynamic library loader 的问题...有很多第三方库可以用的 https://github.com/rainycape/dl
akaHenry
2022-06-13 11:01:16 +08:00
@hhaobao


https://cloud.tencent.com/developer/article/1650525
https://dave.cheney.net/2016/01/18/cgo-is-not-go
https://relistan.com/cgo-when-and-when-not-to-use-it


看这些讨论吧.

除了极端场景, 只有 c/c++ 的库, 需要 binding 给 go 使用. 才用 cgo. 而这个代价, 可能非常高.

即使要用, 请隔离在小服务内. 然后 RPC 暴露给其他服务. 不要污染整个大项目.

这是坨💩. 谁用谁知道.
thewiredguy
2022-06-13 11:06:12 +08:00
C++ 基本上没用过,只能先用 CGO ,回头再用 C++ 写服务了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/859160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX