簡體   English   中英

如何從DLL的導出函數獲取std :: string?

[英]How to get in Go a std::string from an exported function of a DLL?

我想加載自定義DLL(C ++一個)並調用它導出的函數? 這是我的Go代碼:

func main() {
    dllForGo := syscall.MustLoadDLL("dllForGo.dll")
    defer dllForGo.Release()
    getHello:= dllForGo.MustFindProc("getHello")
    r1, _, err := getHello.Call(0) // also tried with .Call() and still got the same error
}

這是我的DLL的C ++代碼:

 std::string __stdcall getHello(void) {
     int a = 1;
     double b = 10;
     return ("Hello-World !!"+std::to_string(a) + std::to_string(b));
}

我試圖強制使用__stdcall(並為此鏈接一個.def文件,因為我認為__declspec(dllexport)可能是個問題)。

但是,使用DUMPBIN,我可以看到getHello使用__cdecl調用約定。 這是個問題嗎?

這是我運行Go時遇到的錯誤:

Exception 0xc0000005 0x1 0x10 0x7fef0591327
PC=0x7fef0591327

syscall.Syscall(0x7fef05910d0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    D:/Go/src/runtime/syscall_windows.go:172 +0xf9
syscall.(*Proc).Call(0xc00004e420, 0xc000058090, 0x1, 0x1, 0x565520, 0x21, 0x2e06a0, 0x0)
    D:/Go/src/syscall/dll_windows.go:146 +0x140
main.main()
    D:/GoLand_Projects/dllLoad/main.go:58 +0x335
rax     0x22fdb8
rbx     0x9
rcx     0x30
rdi     0x9
rsi     0x0
rbp     0x22fdd9
rsp     0x22fd60
r8      0x30303030302e3031
r9      0x7fef1220000
r10     0x22fd90
r11     0x771a1f
r12     0xa
r13     0x9
r14     0x0
r15     0x0
rip     0x7fef0591327
rflags  0x10202
cs      0x33
fs      0x53
gs      0x2b

編輯

getHello函數實際上執行良好。 我修改了它以寫入文件:

 std::string __stdcall  getHello(void) {
     std::ofstream outfile("D:\\test123.txt");
     outfile << "getHello working!" << std::endl;
     outfile.close();
     int a = 1;
     double b = 10;
    return ("Hello-World !!"+std::to_string(a) + std::to_string(b));
}

...然后文件被寫入。 因此問題出在導出函數返回之后。 這使我認為我需要在Go部分中進行一些更改以“歡迎”返回的std :: string。

編輯2

如果我將導出函數的返回類型更改為void ,則Call會毫無例外地返回。 可以暗示它確實與調用約定有關嗎?

這是我從地鼠那里得到的答案:

處理對象非常棘手。 string是一個對象,它可能在某個地方有一個vtable,它也具有一個內部結構(盡管我忘記了它是什么,我想它可能類似於COM bstring或go slice,也許要檢查相關的c ++源代碼)。 調用方法將涉及查找調度表整體的地址並將其作為函數進行調用。 我建議您從C char *開始,然后逐步實現。

因此,我嘗試使用char **作為參數,可以在DLL函數中對其進行修改,並在Go中顯示所做的修改。 我也嘗試返回一個基本類型(int),它也起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM