猿问

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

我想加载自定义 DLL(C++ 之一)并调用它导出的函数?这是我的代码:


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


明月笑刀无情
浏览 164回答 1
1回答

一只甜甜圈

答案:使用对象很棘手。string 是一个对象,它可能在某个地方有一个 vtable,它也有一个内部结构(虽然我忘了它是什么,我猜它类似于 COM bstring 或 go slice,也许检查相关的 c++ 源)。调用方法将涉及查找整个调度表的地址并将它们作为函数调用。我建议您从 C char * 开始,然后按照自己的方式进行。所以我尝试将 char ** 作为参数,我可以在 DLL 函数中修改它并在 Go 中显示修改。我也尝试返回一个基本类型(int)并且它也有效。
随时随地看视频慕课网APP

相关分类

Go
我要回答