GO语言

您所在的位置:网站首页 易语言调用dll闪退 GO语言

GO语言

2024-06-15 01:45| 来源: 网络整理| 查看: 265

编译dll文件(源代码c++):g++ -shared main.cpp -o test.dll

set GOARCH=386

 

第一个DLL函数,第一个参数,要求传入一个指针,直接指向[]byte类型,注意,是直接指向;第2个参数为[]byte长度;第三个参数为一个直接指向string类型指针;返回一个整数,标识调用成功或失败。

最折磨我的就是直接指向某种类型的指针传递问题,查了N多资料,都是类似下面这样:

 

p:= unsafe.Pointer(&dat) g:=dll32.NewProc("XXX") r, _, _ :=g.Call(uintptr(p),uintptr(cdat),uintptr(pk))

我开始也这样用,怎么弄都不对,然后我用OD载入调试,发现传进去的东西根本不是DLL想要的。

 

这样传进去的数据会被2层指针指向,ptrA->ptrB->[]byte,传进去的是ptrA,所以导致无法正常调用。那么问题来了,怎么才能传进去的指针直接指向数据,达到类似ptrA->[]byte这样的效果呢?

问题的重点就在这里,研究了好几天uintptr发现不是它的问题,问题出在

unsafe.Pointer

 

它上面,它会在指针外面再包一层指针,怎么解决呢?我只能考虑先把指针转成整数再传进去,结果

 

p:= *((*int32)(unsafe.Pointer(&dat))) r, _, _ :=g.Call(uintptr(p),uintptr(cdat),uintptr(pk))

这样成功了。下面传递整数指针就简单多了

 

 

cdat:=len(dat)

这样即可,再后面传递字符串指针,指针获取方式和byte一样即可。但是问题又来了,执行不成功,继续OD,发现有问题,问题在于GO语言字符串后面在内存中没有结尾标志。那GO自己怎么判断字符串结尾呢?我想应该是每个字符串GO都同时记录了长度吧,不过不确定,有明白的大神请告知,这个问题我就只能这样,先把字符串转换成byte,然后在byte最后加0,类似这样

 

 

keystr:=[]byte{49,50,51,0} pk:= *((*int32)(unsafe.Pointer(&keystr)))

这个问题就解决了,这个字符串就变成windows识别的了。返回值整数,直接就能用,这点我很奇怪,不知道为什么,比如这里,可以直接

 

 

r, _, _ =g.Call(uintptr(p),uintptr(cdat),uintptr(pk)) if r!=1 {

按理说,返回的是个指向整数的指针,应该*r才对,不懂,大神告知。

 

然后现在所有传递参数的问题解决了,后面问题又来了,第2个函数,调用后返回值是指向字符串的指针,这个指针指向的内容字符串当然是0结尾的windows格式了,GO依然无法正确读取。怎么办呢,只能自己写了个函数处理这个问题

 

//根据DLL返回的指针,逐个取出字节,到0字节时判断为字符串结尾,返回字节数组转成的字符串 func prttostr(vcode uintptr) string { var vbyte []byte for i:=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3