现需要用go写一个运行在win上的常驻服务的客户端,现准备用go来试一下。该客户端会集成多个商家的动态库,故试一下syscall
最新进度
我尼玛,被虐哭了
哈哈哈哈
慢慢补吧
我尼玛,被
有哪些坑
返回string的问题
海康头文件原型1
2// 根据错误号返回错误信息
NET_DVR_API char* __stdcall NET_DVR_GetErrorMsg(LONG *pErrorNo = NULL);
直接说返回值,看到char*,第一反应就是指针;看到char第一反应就是byte
于是:
1 |
|
这样做,也能得到字符串。但是,由于不知道长度,就会把多的字符串赋值进去
后来知道了cgo,上面有一些和c类型的对应,所以试了一下,完美解决
1 | import "C" |
看吧,就最后两句不一样
exit 3221225477
也就是0xc0000005
问题
这是个什么问题?不知道
为什么会有这个问题?不知道
怎么解决这个问题?不知道
我只在设置回调时遇到过这个问题,如果您遇到了,可以对号入座
1 | // 来自头文件 HCNetSDK.h |
在go中这么搞
1 | func NET_DVR_SetDVRMessageCallBack_V31(msgCallback callback.MSGCallBack_V31,pUser unsafe.Pointer) bool { |
可以看到上面代码里面我注释了一句,syscall.NewCallbackCDecl
。
对,就是这一句错了,原因就是两个方法对c函数的约定不同
syscall.NewCallback
调的c函数要符合__stdcall
调用约定
syscall.NewCallbackCDecl
调的c函数要符合__cdecl
调用约定
在海康的头文件里就能看到貌似所有的函数都是__stdcall
的,以头文件中NET_DVR_SetDVRMessageCallBack_V31
为例
1 | // 设置回调,来自头文件 HCNetSDK.h |
总之,如果遇到这个问题,可以考虑一下这个解决方法
一个习惯性问题的坑
我接触的几种语言,默认情况下对象都是用指针传递的,这已经变成习惯了
然后,go的struct也是当成class用的
所以一般的struct变量都会赋一个指针,也不会想太多
1 | type DemoModel struct{ |
然后,海康的某些struct里的属性为另一个struct,比如:
1 | // 检测结果,来自头文件 HCNetSDK.h |
头文件中,属性为值而非指针,然而我下意识的,写上 *
1 | type NET_ITS_PLATE_RESULT struct { |
使用的时候,这些struct字段的值就为nil
这破问题花了我好多时间,真是找不到原因
自己写c++代码来测试(因为我C++代码加了*)都是正常
百度谷歌查了好久,也没找到原因
最后,不知道在排查哪个问题的时候,又看了下头文件,然后说了句卧槽
,终于结束了这次debug
再来个问题
struct 里面的 byte[] 指针问题
后面写,现在远程写的,网不好
调私库的问题
这个与syscall 无关,但既然遇到了,就先记在这里
要做以下事
- 声明私库的网站
比如这样go env -w GOPRIVATE=gitlab.com
- 一般情况,我pc有私库的密钥,用ssh格式的话,不用输密码,则可以转一下格式
比如这样git config --global url.git@gitlab.com:.insteadOf https://gitlab.com/
细节后面补
搜到的问题
关于syscall.callback的个数限制问题
貌似为2000
这里其实我不知道是什么意思
遇到再说
总结
虽然还没写完,但可以先把总结写了
- 调用动态库时,有条件就多看看头文件
理论上说,正确性: 头文件 > 文档 > 其它语言写的demo