2014-12-28 19 views
0

在什麼情況下,去像調用DLL 「CGO執行期間抵達信號」恐慌「信號CGO執行過程中到了」? ;轉到異常

var (
    // entry names found using dumpbin /exports 
    dllSweph = syscall.NewLazyDLL("swedll32.dll") 

    _swe_jdut1_to_utc = dllSweph.NewProc("[email protected]") 
    _swe_julday  = dllSweph.NewProc("[email protected]") 
) 

func swe_julday(year, month, day int32, hour float64, gregflag int32) float64 { 
    r, _, errn := syscall.Syscall6(
     _swe_julday.Addr(), 
     5, 
     uintptr(year), 
     uintptr(month), 
     uintptr(day), 
     uintptr(hour), 
     uintptr(gregflag), 
     0) 

    if r == 0 { 
     if errn != 0 { 
      panic(error(errn)) 
     } 
    } 

    return float64(r) 
} 

func swe_jdut1_to_utc(tjd_ut float64, gregflag int32, iyear, imonth, iday, ihour, imin *int32, dsec *float64) { 
    defer func() { 
     if e := recover(); e != nil { 
     } 
    }() 

    syscall.Syscall9(
     _swe_jdut1_to_utc.Addr(), 
     8, 
     uintptr(tjd_ut), 
     uintptr(gregflag), 
     uintptr(unsafe.Pointer(iyear)), 
     uintptr(unsafe.Pointer(imonth)), 
     uintptr(unsafe.Pointer(iday)), 
     uintptr(unsafe.Pointer(ihour)), 
     uintptr(unsafe.Pointer(imin)), 
     uintptr(unsafe.Pointer(dsec)), 
     0) 
} 

當我打電話swe_julday一切似乎是罰款現在:基於在zsyscall_windows.go樣品中去分佈src -

的代碼被稱爲雖然它不是,它會給出錯誤的答案。當swe_jdut1_to_utc被調用時,我得到:

Exception 0xc0000005 0x1 0x42e5e5 0x3235ce40 
PC=0x3235ce40 
signal arrived during cgo execution 

.../sweph.swe_jdut1_to_utc(0x40000000, 0x4150b979, 0x1, 0x1207bf24, 0x1207bf28, 0x1207bf34, 0x1207bf30, 0x1207bf2c, 0x1207bf38) 
...(trace info) 

eax  0x0 
ebx  0x1207be94 
ecx  0x1207bf38 
edx  0x42e5e5 
edi  0xcfeac 
esi  0x0 
ebp  0xcfe5c 
esp  0xcfdd8 
eip  0x3235ce40 
eflags 0x10246 
cs  0x23 
fs  0x53 
gs  0x2b 
exit status 2 

exit status 1 

環境:

Windows 8 x64 
go 1.4 x86 
gcc  x86 

我不知道,如果gcc真正需要的只是調用DLL,但我已經安裝了它的任何方式,因爲該錯誤約爲cgo。所有命令都在路徑中。使用管理權限編譯時出現同樣的錯誤。

C函數被調用爲:

void swe_jdut1_to_utc (double tjd_ut, int32 gregflag, int32 *iyear, int32 *imonth, int32 *iday, int32 *ihour, int32 *imin, double *dsec) 

而且C#功能,進口和在該DLL(&作品)調用此函數:

[DllImport("swedll32.dll", EntryPoint = "swe_jdut1_to_utc")] 
public static extern void swe_jdut1_to_utc(
    double tjd_ut, 
    int gregflag, 
    ref Int32 iyear, ref Int32 imonth, ref Int32 iday, 
    ref Int32 ihour, ref Int32 imin, ref double dsec); 
+3

0xc0000005是EXCEPTION_ACCESS_VIOLATION。它意味着你的程序中的某個地方,你正試圖讀/寫不存在的內存。例如在0地址或類似的地方閱讀。問題很可能是因爲您的syscall.Syscall9(_swe_jdut1_to_utc ...)參數與您DLL中的相應函數參數不匹配。您必須確保這兩個參數完全匹配:參數號和類型。 – alex

+0

感謝@alex,我已經做了更多的努力並編輯了這個問題。我從'C#'和'F#'調用相同的'dll'(實際上調用''C#''wrappers),它工作正常,並返回正確的答案。 –

+0

我不是'C'專家,但'Go'中的'float64'和'C'中的'double'有可能有不同的結構/定義/內存佈局? –

回答

1

我設法建立使用swe_julday函數的delphi應用程序。不幸的是,我可以看到它使用fstp asm指令來檢索由swe_julday返回的結果。去的是syscall.Syscall不支持這個功能。你是我們的運氣。我認爲你最好的選擇是使用CGO,如果可以使用mingw編譯器構建你的庫。對不起

亞歷克斯

+0

我已經設法使用gcc編譯'C'代碼並創建一個單個目標文件'swe.o'。用cgo可以使用這個目標文件+'.h'文件嗎?直接在C語言源中使用cgo會產生大量錯誤/警告消息,畢竟不會完成這項工作。 –

+0

我在這裏回答了您的問題https://groups.google.com/d/topic/golang-nuts/PqJNf9fK0RQ/discussion讓我們繼續在那裏交談。 – alex