Golang CGO异常0x40010006
Golang CGO Exception 0x40010006
我正在尝试 运行 使用 cgo 的 dll 函数。该库在 C++ 中,所以我在此处创建了一个 C 头文件,其中包含定义的函数和一个 .cpp
文件,其中是实现。
lib.h:
#ifdef __cplusplus
extern "C" {
#endif
void* LoadEngine(char*);
#ifdef __cplusplus
}
#endif
lib.cpp:
#include <Engine.h> //the library
void* LoadEngine(char *sn) {
Engine *e;
GetEngineObject(sn, &e); //function from the dll, here it fails
return (void*) e;
}
然后调用它:
package main
/*
#include "lib.h"
*/
import "C"
func main() {
e := C.LoadEngine(C.CString("foobar")
...
}
我有go1.12 windows/amd64
和 mingw-w64-posix-seh
也试过mingw-w64-posix-sjlj
、mingw-w64-win32-seh
、mingw-w64-win32-sjlj
,但结果是一样的,或者根本无法编译
仅使用 go build
和:
编译它
#cgo windows CFLAGS: -IC:/Engine/Inc
#cgo windows CPPFLAGS: -IC:/Engine/Inc
#cgo windows LDFLAGS: -LC:/Engine/Bin64 -lEngine -lEngineObj -lole32 -loleaut32 -luuid
在 win8 上它 运行 没问题,但在 win10+ 上它不起作用,如果函数调用来自 dll 的 GetEngineObject
,它会失败:
Exception 0x40010006 0x1 0x8deb90 0x7ffbc9ada388
PC=0x7ffbc9ada388
runtime: unknown pc 0x7ffbc9ada388
stack: frame={sp:0x8dea80, fp:0x0} stack=[0x0,0x8dfdf0)
00000000008de980: 0000000002000002 000000002a080321
00000000008de990: 0000000090000191 0000000000000321
00000000008de9a0: 0000000500000008 0000000500000000
00000000008de9b0: feeefeeefeeefeee 00000000024c0150
00000000008de9c0: 0000000000000000 0000000000000000
00000000008de9d0: 00000000024c0000 00007ffbccb730ac
00000000008de9e0: 0000000002680000 00000000024c1e30
00000000008de9f0: 00000000026a2d90 00000000026ad480
00000000008dea00: 0000000000000df1 0000000000000000
00000000008dea10: 0000000000000df1 0000000000000df1
00000000008dea20: 0000000000001bf8 0000000000000000
00000000008dea30: 0000000090000191 0000000000000003
00000000008dea40: 0000bcc3daf1f4cb 00000000026a2d00
00000000008dea50: 0000000000000000 000002fffb442d78
00000000008dea60: 0000000000000000 00000000008dfb00
00000000008dea70: 0000000000000020 00007ffbc9ada388
00000000008dea80: <00000000024c0000 000000002fbe1490
00000000008dea90: 00000000008df970 00000000ffffffff
00000000008deaa0: 0000000040010006 0000000000000000
00000000008deab0: 00007ffbc9ada388 0000000000000002
00000000008deac0: 0000000000000001 00000000008deb90
00000000008dead0: 00000000001b0150 0000000000800000
00000000008deae0: 00000000026ad480 0000000000000000
00000000008deaf0: 00000000001b10b0 0000000000690000
00000000008deb00: 00000000024c0000 00007ffbccbbcafa
00000000008deb10: 00000000024c0000 00007ffbccb76ff8
00000000008deb20: 00000000026a2d90 00000000026a9c30
00000000008deb30: 0000000000000000 0000000000000001
00000000008deb40: 00002c98037a65f6 000000000000001f
00000000008deb50: 00000000026a9430 000000002fd8a367
00000000008deb60: 0000000000006000 00000000024c0000
00000000008deb70: 0000000000000df1 0000000000000000
runtime: unknown pc 0x7ffbc9ada388
stack: frame={sp:0x8dea80, fp:0x0} stack=[0x0,0x8dfdf0)
00000000008de980: 0000000002000002 000000002a080321
00000000008de990: 0000000090000191 0000000000000321
00000000008de9a0: 0000000500000008 0000000500000000
00000000008de9b0: feeefeeefeeefeee 00000000024c0150
00000000008de9c0: 0000000000000000 0000000000000000
00000000008de9d0: 00000000024c0000 00007ffbccb730ac
00000000008de9e0: 0000000002680000 00000000024c1e30
00000000008de9f0: 00000000026a2d90 00000000026ad480
00000000008dea00: 0000000000000df1 0000000000000000
00000000008dea10: 0000000000000df1 0000000000000df1
00000000008dea20: 0000000000001bf8 0000000000000000
00000000008dea30: 0000000090000191 0000000000000003
00000000008dea40: 0000bcc3daf1f4cb 00000000026a2d00
00000000008dea50: 0000000000000000 000002fffb442d78
00000000008dea60: 0000000000000000 00000000008dfb00
00000000008dea70: 0000000000000020 00007ffbc9ada388
00000000008dea80: <00000000024c0000 000000002fbe1490
00000000008dea90: 00000000008df970 00000000ffffffff
00000000008deaa0: 0000000040010006 0000000000000000
00000000008deab0: 00007ffbc9ada388 0000000000000002
00000000008deac0: 0000000000000001 00000000008deb90
00000000008dead0: 00000000001b0150 0000000000800000
00000000008deae0: 00000000026ad480 0000000000000000
00000000008deaf0: 00000000001b10b0 0000000000690000
00000000008deb00: 00000000024c0000 00007ffbccbbcafa
00000000008deb10: 00000000024c0000 00007ffbccb76ff8
00000000008deb20: 00000000026a2d90 00000000026a9c30
00000000008deb30: 0000000000000000 0000000000000001
00000000008deb40: 00002c98037a65f6 000000000000001f
00000000008deb50: 00000000026a9430 000000002fd8a367
00000000008deb60: 0000000000006000 00000000024c0000
00000000008deb70: 0000000000000df1 0000000000000000
goroutine 1 [syscall]:
path/to/package._Cfunc_LoadEngine(0x23a2c20, 0x0)
_cgo_gotypes.go:518 +0x51
path/to/package.Load(0x4d05ad, 0x1d, 0x0, 0x0, 0x0)
C:/Users/microo8/Documents/workspace/src/path/to/package/fre.go:55 +0x89
main.main()
W:/Workspace/src/path/to/package/test/test.go:12 +0x41
rax 0x3e00003e
rbx 0x2fbe1490
rcx 0xfffffffffffffffe
rdi 0xffffffff
rsi 0x8df970
rbp 0x20
rsp 0x8dea80
r8 0x2fca2793
r9 0x3a0f4c0
r10 0x2fca2701
r11 0x26aadb0
r12 0x8dfb00
r13 0x0
r14 0x2fffb442d78
r15 0x0
rip 0x7ffbc9ada388
rflags 0x202
cs 0x33
fs 0x53
gs 0x2b
我也尝试用 mingw 的 __try1
和 __except1
捕获异常,但无论如何都失败了。尝试了不同的 mingw 版本,使用 -ldflags="-linkmode internal"
但这不会编译并且 -ldflags="-linkmode external"
也会出现此异常。
编辑: 还尝试从 C 程序调用 LoadEngine
函数(来自 lib.h
)并且它工作正常。将 lib.cpp
与 g++
编译为 lib.o
。并将其链接到 test.c
,我刚刚从 main
函数中调用了 LoadEngine
。所以也许有什么问题如何将库链接到 cgo?
出于某种原因,在 win10+ 上它会提高 DBG_PRINTEXCEPTION_C
。这是由 OutputDebugStringW
引起的,没有调试器在侦听。
我认为通常它会用微软的 __try and __except 来完成,但在 MinGW 中只有 __try1 和 __except1,我认为它们只适用于 32 位系统(很少有文档是那个)
但我发现,您可以添加一个 Exception Handler
所以现在 lib.cpp:
#include <Engine.h> //the library
#ifdef _WIN32
#include <windows.h>
LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
UNREFERENCED_PARAMETER(ExceptionInfo);
return EXCEPTION_CONTINUE_EXECUTION; //just continue
}
#endif
void* LoadEngine(char *sn) {
#ifdef _WIN32
PVOID handler = AddVectoredContinueHandler(1, VectoredHandler);
#endif
Engine *e;
GetEngineObject(sn, &e);
#ifdef _WIN32
RemoveVectoredContinueHandler(handler);
#endif
return (void*) e;
}
因为使用库从加载引擎开始并以卸载它结束,并且引擎是一个单例,所以我刚刚让 PVOID handler
也是一个全局单例,而 AddVectoredContinueHandler
是在 LoadEngine
和 RemoveVectoredContinueHandler
在 UnloadEngine
.
我正在尝试 运行 使用 cgo 的 dll 函数。该库在 C++ 中,所以我在此处创建了一个 C 头文件,其中包含定义的函数和一个 .cpp
文件,其中是实现。
lib.h:
#ifdef __cplusplus
extern "C" {
#endif
void* LoadEngine(char*);
#ifdef __cplusplus
}
#endif
lib.cpp:
#include <Engine.h> //the library
void* LoadEngine(char *sn) {
Engine *e;
GetEngineObject(sn, &e); //function from the dll, here it fails
return (void*) e;
}
然后调用它:
package main
/*
#include "lib.h"
*/
import "C"
func main() {
e := C.LoadEngine(C.CString("foobar")
...
}
我有go1.12 windows/amd64
和 mingw-w64-posix-seh
也试过mingw-w64-posix-sjlj
、mingw-w64-win32-seh
、mingw-w64-win32-sjlj
,但结果是一样的,或者根本无法编译
仅使用 go build
和:
#cgo windows CFLAGS: -IC:/Engine/Inc
#cgo windows CPPFLAGS: -IC:/Engine/Inc
#cgo windows LDFLAGS: -LC:/Engine/Bin64 -lEngine -lEngineObj -lole32 -loleaut32 -luuid
在 win8 上它 运行 没问题,但在 win10+ 上它不起作用,如果函数调用来自 dll 的 GetEngineObject
,它会失败:
Exception 0x40010006 0x1 0x8deb90 0x7ffbc9ada388
PC=0x7ffbc9ada388
runtime: unknown pc 0x7ffbc9ada388
stack: frame={sp:0x8dea80, fp:0x0} stack=[0x0,0x8dfdf0)
00000000008de980: 0000000002000002 000000002a080321
00000000008de990: 0000000090000191 0000000000000321
00000000008de9a0: 0000000500000008 0000000500000000
00000000008de9b0: feeefeeefeeefeee 00000000024c0150
00000000008de9c0: 0000000000000000 0000000000000000
00000000008de9d0: 00000000024c0000 00007ffbccb730ac
00000000008de9e0: 0000000002680000 00000000024c1e30
00000000008de9f0: 00000000026a2d90 00000000026ad480
00000000008dea00: 0000000000000df1 0000000000000000
00000000008dea10: 0000000000000df1 0000000000000df1
00000000008dea20: 0000000000001bf8 0000000000000000
00000000008dea30: 0000000090000191 0000000000000003
00000000008dea40: 0000bcc3daf1f4cb 00000000026a2d00
00000000008dea50: 0000000000000000 000002fffb442d78
00000000008dea60: 0000000000000000 00000000008dfb00
00000000008dea70: 0000000000000020 00007ffbc9ada388
00000000008dea80: <00000000024c0000 000000002fbe1490
00000000008dea90: 00000000008df970 00000000ffffffff
00000000008deaa0: 0000000040010006 0000000000000000
00000000008deab0: 00007ffbc9ada388 0000000000000002
00000000008deac0: 0000000000000001 00000000008deb90
00000000008dead0: 00000000001b0150 0000000000800000
00000000008deae0: 00000000026ad480 0000000000000000
00000000008deaf0: 00000000001b10b0 0000000000690000
00000000008deb00: 00000000024c0000 00007ffbccbbcafa
00000000008deb10: 00000000024c0000 00007ffbccb76ff8
00000000008deb20: 00000000026a2d90 00000000026a9c30
00000000008deb30: 0000000000000000 0000000000000001
00000000008deb40: 00002c98037a65f6 000000000000001f
00000000008deb50: 00000000026a9430 000000002fd8a367
00000000008deb60: 0000000000006000 00000000024c0000
00000000008deb70: 0000000000000df1 0000000000000000
runtime: unknown pc 0x7ffbc9ada388
stack: frame={sp:0x8dea80, fp:0x0} stack=[0x0,0x8dfdf0)
00000000008de980: 0000000002000002 000000002a080321
00000000008de990: 0000000090000191 0000000000000321
00000000008de9a0: 0000000500000008 0000000500000000
00000000008de9b0: feeefeeefeeefeee 00000000024c0150
00000000008de9c0: 0000000000000000 0000000000000000
00000000008de9d0: 00000000024c0000 00007ffbccb730ac
00000000008de9e0: 0000000002680000 00000000024c1e30
00000000008de9f0: 00000000026a2d90 00000000026ad480
00000000008dea00: 0000000000000df1 0000000000000000
00000000008dea10: 0000000000000df1 0000000000000df1
00000000008dea20: 0000000000001bf8 0000000000000000
00000000008dea30: 0000000090000191 0000000000000003
00000000008dea40: 0000bcc3daf1f4cb 00000000026a2d00
00000000008dea50: 0000000000000000 000002fffb442d78
00000000008dea60: 0000000000000000 00000000008dfb00
00000000008dea70: 0000000000000020 00007ffbc9ada388
00000000008dea80: <00000000024c0000 000000002fbe1490
00000000008dea90: 00000000008df970 00000000ffffffff
00000000008deaa0: 0000000040010006 0000000000000000
00000000008deab0: 00007ffbc9ada388 0000000000000002
00000000008deac0: 0000000000000001 00000000008deb90
00000000008dead0: 00000000001b0150 0000000000800000
00000000008deae0: 00000000026ad480 0000000000000000
00000000008deaf0: 00000000001b10b0 0000000000690000
00000000008deb00: 00000000024c0000 00007ffbccbbcafa
00000000008deb10: 00000000024c0000 00007ffbccb76ff8
00000000008deb20: 00000000026a2d90 00000000026a9c30
00000000008deb30: 0000000000000000 0000000000000001
00000000008deb40: 00002c98037a65f6 000000000000001f
00000000008deb50: 00000000026a9430 000000002fd8a367
00000000008deb60: 0000000000006000 00000000024c0000
00000000008deb70: 0000000000000df1 0000000000000000
goroutine 1 [syscall]:
path/to/package._Cfunc_LoadEngine(0x23a2c20, 0x0)
_cgo_gotypes.go:518 +0x51
path/to/package.Load(0x4d05ad, 0x1d, 0x0, 0x0, 0x0)
C:/Users/microo8/Documents/workspace/src/path/to/package/fre.go:55 +0x89
main.main()
W:/Workspace/src/path/to/package/test/test.go:12 +0x41
rax 0x3e00003e
rbx 0x2fbe1490
rcx 0xfffffffffffffffe
rdi 0xffffffff
rsi 0x8df970
rbp 0x20
rsp 0x8dea80
r8 0x2fca2793
r9 0x3a0f4c0
r10 0x2fca2701
r11 0x26aadb0
r12 0x8dfb00
r13 0x0
r14 0x2fffb442d78
r15 0x0
rip 0x7ffbc9ada388
rflags 0x202
cs 0x33
fs 0x53
gs 0x2b
我也尝试用 mingw 的 __try1
和 __except1
捕获异常,但无论如何都失败了。尝试了不同的 mingw 版本,使用 -ldflags="-linkmode internal"
但这不会编译并且 -ldflags="-linkmode external"
也会出现此异常。
编辑: 还尝试从 C 程序调用 LoadEngine
函数(来自 lib.h
)并且它工作正常。将 lib.cpp
与 g++
编译为 lib.o
。并将其链接到 test.c
,我刚刚从 main
函数中调用了 LoadEngine
。所以也许有什么问题如何将库链接到 cgo?
出于某种原因,在 win10+ 上它会提高 DBG_PRINTEXCEPTION_C
。这是由 OutputDebugStringW
引起的,没有调试器在侦听。
我认为通常它会用微软的 __try and __except 来完成,但在 MinGW 中只有 __try1 和 __except1,我认为它们只适用于 32 位系统(很少有文档是那个)
但我发现,您可以添加一个 Exception Handler
所以现在 lib.cpp:
#include <Engine.h> //the library
#ifdef _WIN32
#include <windows.h>
LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
UNREFERENCED_PARAMETER(ExceptionInfo);
return EXCEPTION_CONTINUE_EXECUTION; //just continue
}
#endif
void* LoadEngine(char *sn) {
#ifdef _WIN32
PVOID handler = AddVectoredContinueHandler(1, VectoredHandler);
#endif
Engine *e;
GetEngineObject(sn, &e);
#ifdef _WIN32
RemoveVectoredContinueHandler(handler);
#endif
return (void*) e;
}
因为使用库从加载引擎开始并以卸载它结束,并且引擎是一个单例,所以我刚刚让 PVOID handler
也是一个全局单例,而 AddVectoredContinueHandler
是在 LoadEngine
和 RemoveVectoredContinueHandler
在 UnloadEngine
.