我用 golang 调用 c++ dll,调用成功,传值成功(代码省略其他无用的,仅细节代码):
```
inst := syscall.MustLoadDLL("test.dll");
some_func := inst.MustFindProc("test_function");
s1: = "aaa" // 传递参数给 c++ dll
s2:= "bbb" // 传递参数给 c++ dll
s3:="" // 我希望从这个参数得到返回值
some_func.Call( uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s1),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s2)
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s3))
```
现在在 c++ 的 test_function 里面能够给收到传递过来的数据了,但是,我该如何给 s3 赋值呢?试了很多种办法,s3 的值在 go 这边看不到,不是很懂这个原理,求大神指点。
另外我的要求其实很简单,就是从**参数,或者返回值**能获取到 c++ 返回的**字符串类型**的值(不是 int),求大神帮忙给个办法。
冰天雪地赤身Luo体360°托马斯旋转烧香拜佛跪破膝盖 求解救办法...
1. 会造成泄漏。C返回的指针不会被Go引用计数,因此也不会被垃圾回收。解决方法可以在dll中实现释放的接口,在Go中调用。
2. 一楼解释得很明白了,这里略做补充:syscall.Proc.Call返回uintptr表示内存地址,直接操作这个地址即可,以下代码未经仔细推敲,仅供参考:
```go
r, _, _ := some_func.Call()
p := (*byte)(unsafe.Pointer(r))
data := make([]byte, 0)
for *p != 0 {
data = append(data, *p)
r += unsafe.Sizeof(byte(0))
p = (*byte)(unsafe.Pointer(r))
}
s := string(data)
```
#4
更多评论
C++返回值应该是 char* ,返回的是指针,然后在Go中对这个int类型进行转换变成 指向 byte的指针,解引用就读出了这个 字节的值。C++中char* 类型是连续内存结构,最后以'0x00‘结尾,所以每读取依次 byte 对传回来的 指针进行偏移1 操作直到读取到'0x00‘ 认为是结尾。再把这个[]byte转换成 string就可以了。
首先要明确就是就是C++中的编码形式。
#1
首先三叩九拜跪谢大神。
其次有几个问题想请教下:
1. 目前 c++ 这边如果返回一个指针,显然不能返回栈上开辟的,也就是应该搞个 new 出来的玩意返回,否则c++函数返回后,go这边得到的是一个已经被释放了的,但是问题来了,go得到这个指针后,又不能释放,是不是造成了内存泄漏?
2. c++ 这边的返回 char 应该如何被 go 转换呢,新手不懂 ^_^
再次六体投地请大神解答
#2