c - 将 jvm 库动态加载到 windows 上的 go 代码中
问题描述
我正在使用 windows 上的 cgo 绑定将 jvm.dll 加载到 go 程序中(GOOS=windows;GOARCH=amd64)。JDK 已安装并在 PATH 变量中配置以下内容:
- c:\Program Files\Java\jdk1.8.0_231\bin\
- c:\Program Files\Java\jdk1.8.0_231\jre\bin\server\
c:\Program Files\Java\jdk1.8.0_231\jre\bin\
%_ALT_JAVA_HOME_DIR% 设置为“c:\Program Files\Java\jdk1.8.0_231\jre\”
C代码如下:
JVM *jvm;
jvm = malloc(sizeof(JVM));
JavaVMInitArgs vm_args;
vm_args.version=JNI_VERSION_1_8;
jint ret = JNI_CreateJavaVM(&jvm->jvm, (void **)&jvm->env, &vm_args);
}
正在调用下面的代码
import "C"
import (
"syscall"
"unsafe"
)
var mod, _ = syscall.LoadLibrary("jvm.dll")
var createJvm, _ = syscall.GetProcAddress(mod, "JNI_CreateJavaVM")
var getDefaultArgs,_ = syscall.GetProcAddress(mod, "JNI_GetDefaultJavaVMInitArgs")
//export JNI_CreateJavaVM
func JNI_CreateJavaVM(jvm unsafe.Pointer, env unsafe.Pointer, args unsafe.Pointer) int32 {
println("jvm", jvm)
println("env", env)
println("args", args)
var resCode, _, err = syscall.Syscall(uintptr(getDefaultArgs), 1, uintptr(args),0,0);
println("result of JNI_GetDefaultJavaVMInitArgs", int32( resCode), err)
resCode, _, err = syscall.Syscall(uintptr(createJvm), 3, uintptr(jvm), uintptr(env), uintptr(args));
println("result of JNI_CreateJavaVM", int32( resCode), err)
return int32(resCode);
}
在第二个系统调用代码失败,输出如下:
env 0xe05de0
args 0x86fcf0
result of JNI_GetDefaultJavaVMInitArgs 0 0
Exception 0xc0000005 0x0 0x0 0x286503b6
PC=0x286503b6
signal arrived during external code execution
syscall.Syscall(0x6caae840, 0x3, 0xe05de8, 0xe05de0, 0x86fcf0, 0x0, 0x0, 0x0)
C:/Users/user/sdk/go1.14rc1/src/runtime/syscall_windows.go:188 +0xe9
test/jni.JNI_CreateJavaVM(0xe05de8, 0xe05de0, 0x86fcf0, 0x0)
C:/Users/user/IdeaProjects/test/jni/jni.go:21 +0x1c1
test/jni._cgoexpwrap_c7fe4a664520_JNI_CreateJavaVM(0xe05de8, 0xe05de0, 0x86fcf0, 0x7ffada619da0)
_cgo_gotypes.go:467 +0x46
test/jni._Cfunc_createJVM(0xe01a50, 0x6, 0x0)
_cgo_gotypes.go:407 +0x55
test/jni.CreateJVM.func3(0xe01a50, 0xc000035f18, 0x6, 0x6, 0xc000004280)
C:/Users/user/IdeaProjects/test/jni/jvm.go:41 +0x5d
test/jni.CreateJVM(0xc000035f18, 0x6, 0x6, 0x0)
C:/Users/user/IdeaProjects/test/jni/jvm.go:41 +0x14e
main.main()
C:/Users/user/IdeaProjects/test/main.go:16 +0xf3
rax 0x6
rbx 0x100800
rcx 0xcafebabe
rdi 0x1
rsi 0x0
rbp 0x6d16f550
rsp 0x86f258
r8 0x2865047b
r9 0x86f420
r10 0x2
r11 0x86f590
r12 0x3d8
r13 0x0
r14 0x0
r15 0x2030000
rip 0x286503b6
rflags 0x210246
cs 0x33
fs 0x53
gs 0x2b
我检查并确认 jvm.dll 已加载,两个符号都可用,对 JNI_GetDefaultJavaVMInitArgs 的调用成功。有什么想法可以查看以及对 JNI_CreateJavaVM 的调用有什么问题?
解决方案
好的,这样的行为是由https://github.com/golang/go/issues/20498引起的。为了绕过错误,需要调整 go 源代码: src/runtime/signal_windows.go#127 应该从 var testingWER bool 更改为 var testingWER=true
推荐阅读
- sql - 带变量的 SQL 重用 Select 子句
- java - Disruptor 和 ExecutorService 有什么区别
- java - Spring 集成:映射 - 默认分支
- python - For循环将列表中的项目与熊猫前行中的所有项目进行比较
- flutter - 颤振谷歌地图地点选择器仅在特定缩放范围内选择地址,搜索和客户图像图标
- pyserial - pySerial 和 Nios II
- python - Matplotlib 以一种非常奇怪的方式绘制图形
- git - 如何确定提交中是否添加、修改或删除了每个文件?
- scala - Kafka Streams App 在启动后几秒钟内退出
- matlab - WORHP 13.2 运行示例文件时崩溃