代码之家  ›  专栏  ›  技术社区  ›  microo8

Golang CGO异常0x40010006

  •  0
  • microo8  · 技术社区  · 5 年前

    我试着用cgo从dll运行一个函数。这个库是c++的,所以我创建了一个c头,这里是定义的函数和 .cpp

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void* LoadEngine(char*);
    
    #ifdef __cplusplus
    }
    #endif
    
    

    库.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+上,如果函数开始调用 GetEngineObject 来自dll的,它失败的原因是:

    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
    

    我也试着抓住明的例外 __try1 __except1 但无论如何都失败了。尝试了不同的mingw版本,使用 -ldflags="-linkmode internal" 但这不是编译和 -ldflags="-linkmode external" 也有例外。

    编辑: 也试着打电话给 LoadEngine 函数(从 lib.h lib.cpp 具有 g++ lib.o test.c 我刚打电话给 装载机 只是从 main

    0 回复  |  直到 5 年前
        1
  •  0
  •   microo8    5 年前

    出于某种原因,在win10+上它会提高 DBG_PRINTEXCEPTION_C . 这是由于 OutputDebugStringW

    我想通常情况下,微软的 __try and __except

    但我发现,你可以加一个 Exception Handler

    那么现在呢库.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 .