关于char 传递二进制参数的问题

声明:本人为新手,看了大约2个星期,可能有其它的解决方案
事情的经过是这样的,项目准备使用quick 作为框架 和现有的服务器系统 进行对接。
服务器采用的是长连接+protobuf ,然后开始了 , 接SocketNet 接protobuf (此处略去,可以参考网上的教程。。。)
下面问题来了 ,协议中采用了crc数据校验,来保证发送的消息是可靠的,我首先用c++实现了一个crc32的算法(网上一大堆)
发送测试了下 ,发现计算出来的crc码是错误的,而且在消息一样的情况下 ,每次生成的校验码都不一样,将接口实现的类在单独程序里打印的结果是正确的,服务器打印日志crc校验错误
因为在组包的时候还有其他问题,我决定放弃,找了个lua的crc版本,这次过了。如果你觉得到这里就结束了,那你就错了,
在后面的测试中,发现有时候crc校验码 有时候对,有时候不对,观察后发现,lua代码改动的时候 ,加个printf ,减个printf都会影响运算结果,
我这就抽了,我决定仔细检查下到底哪里有问题了,

std::string arg1_tmp; ok &= luaval_to_std_string(tolua_S, 3, &arg1_tmp, "aFunc:getCRC"); arg1 = arg1_tmp.c_str();

我在动生成的lua接口函数里看到了这句话。。。 这个看起来不大靠谱的样子咯。。。。测试了下 ,果然传入的字符串,比实际的要少, 观察 这个函数luaval_to_std_string 里获取string 参数的方法是这个tolua_tocppstring
发现在这个接口是不支持二进制字串的 遇到“\0” 就会结束掉,擦
然后我在tolua的代码下面看到了这个接口tolua_tofieldcppstring ,从名字上看应该是可以支持数组的,然后拿出来试下,我在cocos里的LuaBasicConversions.cpp 加了下面的代码

]

bool luaval_to_field_string(lua_State* L, int lo, std::string* outValue, int size,const char* funcName)
{
if (NULL == L || NULL == outValue)
return false;

bool ok = true;

tolua_Error tolua_err;
if (!tolua_iscppstringarray(L,lo,1,0,&tolua_err))
{
#if COCOS2D_DEBUG >=1
luaval_to_native_err(L,"#ferror:",&tolua_err,funcName);
#endif

ok = false;
}

if (ok)
{
outValue->append(tolua_tofieldcppstring(L,lo,1,NULL),size);
}

return ok;
}

对应的.h文件里加上这个

extern bool luaval_to_field_string(lua_State* L, int lo, std::string* outValue,int size, const char* funcName = "");

luaval_to_std_string 替换成 luaval_to_field_string 测试下 local crcvalue = crc32.getCRC({crcstr}),这下ok了。当然,后来发现网上找的crc算法也是也对的,错误出现在ByteArray的使用上 我是用writeInt方法把crc的结果写进去的,但是发现当crcvalue > 21亿的时候 ByteArray 直接写了个-1…
好丢人 改成writeUInt,就好了。 但是总的来说 ,如果需要用二进制字串传入的话 上面的代码还是可以用的,cocos自动生成脚本就不改了,有需要的请手动改下。如果有其他的方法 ,请告知,一起学习进步^_^