使用hiredis报错LNK2005

一、编译报错 LNK1169、LNK2005

项目的dbsdk使用了redis+python+mysql的存储方案.
在编译hiredis库的时候,win32_interop.lib与项目中原有的net.lib有编译冲突。net.lib引用了ws2_32.libwin32_interop.lib也包含了ws2_32.lib。这样当项目同时引用net.libwin32_interop.lib时,就会出现重定义的LNK错误。
例如图中的使用tcp的几个接口:accept()、bind()

解决方案 :

  1. 修改了hiredis的源码,hiredis.lib和win32_interop.lib的源代码中,但凡使用了tcp网络接口的地方,都将函数重命名。例如bind()、accept()接口全部加了前缀redis_,变为redis_bind()、redis_accept()。再重新编译导出win32_interop.lib。放入工程中,编译正常通过。
  2. 修改完源码以后,工程编译x64版本,发现启动项目后,项目无法正常连接上redis。这里是个人遗漏引起的,原因:调用hiredis.lib的redisConnect()接口,其底层还是调用tcp的connect()接口。编译时,connect()函数没有报错,我就没有全修改,导致遗漏。索性把所有网络相关的接口,全部修改后,再编译hiredis.lib导出到工程引用后,不可连接的问题解决,可以正常连接上redis。
  3. x64环境下,redisCommand()执行%b参数会报错 “Out of memory”,需要将redisCommand()中int类型修改为size_t类型(还是去修改hiredis的源码,然后编译导出新的lib文件)。
    因为size_t会自动识别x64和win32,在win32下是4字节,在x64是8字节。
    redisCommand()中%b的长度默认类型是int,导致在win32下没有问题,但编译x64就会报错。

二、dbsdk.lib编码问题

python代码中,用encode(“utf-8”)将数据转换为utf-8格式的二进制数据。
decode()函数将二进制数据解码为字符串。
utf-8编码的二进制数据,解码也要utf-8格式,否则解析出来的数据会是乱码。

二进制数据解码为json字符串,如果二进制数据中包含\0json字符串提前截断,从而导致json字符串和二进制数据对不上。相当于数据被截断丢失了。
json也不支持直接存储二进制数据。

解决方案:将二进制数据用base64算法编码为字符串,这样就可以存储到json中,进而将组装的json数据存储到redis中。
dbsdk.libredis中取出base64编码后的json字符串。在dbsdk层同样用base64解码json字符串。在转换回二进制数据。
python:blob > base64 > string > json > redis
dbsdk : redis > json > string > base64 > blob

三、hiredis库的高并发

之前dbsdk调用的hiredis的同步接口redisCommand(),当一帧存储100个玩家的时候,同步接口会阻塞挂起线程,导致服务器无法响应客户端的请求。有两个方案:

  1. dbsdk不再调用同步接口,改为调用异步接口redisAsyncCommand()。
  2. 在dbsdk开一条写线程,专门负责和redis交互,和游戏主线程独立开。这样也不会卡住game_server。
    这里采用的方案一,主要是不想重复造轮子,而且不一定写的有人家好。

异步接口在linux下支持比较完善,redis提供了epoll模型。
但是在redis不怎么支持windows环境。需要另外找一个win32_interop的工程,貌似是微软自己去支持的redis(卑微)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值