我在尝试通过 JNI 调用隐语 PIR 的功能,需要构建一个.so动态库给 Java 使用。 目前我手动用 g++ -shared 去链接,但遇到了依赖符号缺失问题(例如 absl::lts_20240722::Symbolize,以及 SEAL 的 MemoryPoolMT)。 我注意到 bazel-bin/external 下已经有编译好的依赖(seal、absl、yacl 等),但是我不确定应该如何用 Bazel 把它们正确打包进 libyinyu_pir_jni.so。 在隐语的工程里,是否有推荐的方式/示例来用 Bazel 构建 JNI 动态库?
Activity
hsz0797 commentedon Sep 15, 2025
huocun-ant commentedon Sep 15, 2025
使用
cc_shared_library试试,类似
其中,exported_symbols.lds文件可以导出你想使用的接口函数名,类似:
hsz0797 commentedon Sep 15, 2025
试了一下,又有新问题,搞不明白了

这是BUILD.bazel,exported_symbols.lds导出了想使用的接口函数名
`# demo/src/main/jni/BUILD.bazel
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
exports_files(["exported_symbols.lds"])
cc_library(
name = "jni_headers",
hdrs = [
"jni.h",
"jni_md.h",
],
includes = ["."],
visibility = ["//visibility:public"],
)
cc_library(
name = "yinyu_pir_native_lib",
srcs = [
"com_secretflow_pir_SecretFlowPirNativeUtils.cpp",
],
hdrs = [
"com_secretflow_pir_SecretFlowPirNativeUtils.h",
],
includes = ["."],
copts = [
"-std=c++17",
"-fPIC",
],
deps = [
":jni_headers",
"//psi/wrapper/apsi/api:sender_c_wrapper",
"//psi/wrapper/apsi/api:receiver_c_wrapper",
"//psi/wrapper/apsi/api:sender",
"//psi/wrapper/apsi/api:receiver",
"//psi/wrapper/apsi/api:wrapper_util",
],
visibility = ["//visibility:public"],
)
cc_binary(
name = "yinyu_pir_jni",
deps = [
":yinyu_pir_native_lib",
],
linkshared = 1,
linkstatic = 0,
additional_linker_inputs = [":exported_symbols.lds"],
linkopts = [
"-Wl,--version-script=$(location :exported_symbols.lds)",
"-Wl,-rpath,$ORIGIN",
],
data = [":exported_symbols.lds"],
visibility = ["//visibility:public"],
)
`
huocun-ant commentedon Sep 17, 2025
C++的函数签名会name mangle,如果是是Java想访问C++的函数,可以搞个C的header,也就是所有导出的函数使用extern "C" {} 包起来,可以网上搜一下标准写法,另外建议给这一组C 接口提供一个公共的前缀,这样方便导出,如果导出的接口中会包含C++的类作为参数,可以用void*暴露出去
huocun-ant commentedon Sep 17, 2025
编译好的so可以使用命令 ldd -r xxx.so看看是不是需要别的so或者有unresolve的符号
huocun-ant commentedon Sep 17, 2025
这个提示的符号可以使用如下命令查看: