如何从DLL的导出函数获取std :: string?

时间:2019-01-08 02:10:17

标签: c++ go dll 64-bit

我想加载自定义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。

EDIT2

如果我将导出函数的返回类型更改为 void ,则Call会无例外地返回。可以暗示它确实与调用约定有关吗?

1 个答案:

答案 0 :(得分:0)

这是我从地鼠那里得到的答案:

  

处理对象非常棘手。字符串是一个对象,它可能有一个   vtable的某个地方,它也具有内部结构(尽管我忘记了   这是什么,我猜是类似于COM bstring或go   切片,也许检查相关的c ++来源)。调用方法将   涉及查找调度表整体的地址并调用   那些作为功能。我建议您从C char *开始,然后   的方式。

因此,我尝试使用char **作为参数,我可以在DLL函数中对其进行修改,并在Go中显示所做的修改。我还尝试返回一个基本类型(int),它也起作用。