标准MFC WinSock ActiveX控件开发实例(II)高级篇
2009-05-11 20:06:17 来源:WEB开发网在这里,我们利用了_com_util::ConvertBSTRToString() 将BSTR转换成char *类型,它能自动对中文字符进行转换,解决了利用某些方法转换时,中文字符变成乱码的BUG。前提是,在使用该方法时,你要先 #include "comutil.h" ,然后在Project Settings-Link-Object/library modules 中加入" comsupp.lib kernel32.lib "
同理,将char *转换成BSTR类型,可以通过_com_util::ConvertStringToBSTR()实现。在VC中,通过sizeof()我们可以看到int和long的长度都是4,而char的长度为1,因此,如果传入的是长整型或者整型数组,我将它转换成4个char,然后发送出去,转换方法可以通过移位处理,如下 :
//long转换为4个char
char buffer[4];
long lData_1 = 12345678;
long lData_2 = 0;
buffer[0] = (lData>>24)&0xff;
buffer[1] = (lData>>16)&0xff;
buffer[2] = (lData>>8)&0xff;
buffer[3] = lData&0xff;
//4个char组成一个long
lData_2 = ((buffer[0]&0xff)<<24) +
((buffer[1]&0xff)<<16) +
((buffer[2]&0xff)<<8) +
(buffer[3]&0xff);
四、现在来看看GetData()的处理,具体实现,请看如下代码:
// TODO: Add your dispatch handler code here
if(!OnlySock)
return -1;//网络尚未开始建立连接
int gDataType = VariantToLong(DataType);
long gDataMaxLength = VariantToLong(DataMaxLength);
int gTimeOut = VariantToLong(TimeOut);
if(gDataType < 0)
return -2;
if(gDataMaxLength <= 0)
return -2;
if(gTimeOut < 0)
return -2;
switch(gDataType)
{
case 0://默认形式,这时如果发现Data为整型数组,将不进行任何转换,直接把一个int传给一个char传送(数据可能溢出范围)
case 1://当指定该值为1时,当Date为长整型数组时,将把一个long转换成四个char传送
case 2://当指定该值为2时,当Date为整型数组时,将把一个int转换成四个char传送
case 3://当指定该值为3时,当Date为无符号短整型数组时,将把一个unsigned short转换成两个char传送
case 4://当指定该值为4时,当Date为BYTE数组时,将把一个BYTE转换成一个char传送
case 5://当指定该值为5时,当Date为短整型数组时,将把一个short转换成两个char传送
case 6://当指定该值为6时,当Date为浮点型数组时,将把一个float转换成四个char传送
case 7://当指定该值为7时,当Date为双精度数组时,将把一个double转换成八个char传送
break;
default://如果不在上面取值范围内,将按当前的Data相应类型进行传送
break;
}
timeval tv;
fd_set fdread;
int len = -3;//如果找不到该连接,则返回-3
long n = 0;
long m = 0;
long changetype = 0;
VARIANT gData;
VariantInit(&gData);
char *buffer=NULL;
buffer = new char[gDataMaxLength+1];
memset(buffer, 0, gDataMaxLength+1);
FD_ZERO(&fdread);
tv.tv_sec = gTimeOut;//超过指定时间后返回
tv.tv_usec = 0;
FD_SET(OnlySock,&fdread);//是否可以读取数据
select( 0,&fdread,NULL,NULL,&tv);
if(FD_ISSET(OnlySock,&fdread))
{
len = recv(OnlySock, buffer, gDataMaxLength, 0);
if (len<=0)
{
delete[] buffer;
return -102;//无法读取数据,对方可能已断开连接
}
if(len<gDataMaxLength)//如果读取数据的长度小于传入的长度,将传入的长度更改为实际长度
gDataMaxLength = len;
switch(Data->vt)
{
case VT_BSTR://按字符串形式接收
buffer[gDataMaxLength] = '';
Data->bstrVal = _com_util::ConvertStringToBSTR(buffer);
break;
case VT_BYREF|VT_UI1:
//按BYTE*形式接收
memcpy(Data->pbVal,buffer,gDataMaxLength);
break;
case VT_BYREF|VT_I1://按 char * 形式接收
memcpy(Data->pcVal,buffer,gDataMaxLength);
break;
case VT_BYREF|VT_I4://以长整型指针接收
buffer[gDataMaxLength]='';
for(n=0; n<gDataMaxLength; n++)
{
Data->plVal[n] = buffer[n];
}
break;
case VT_ARRAY|VT_I4://以长整型数组接收
gData.vt = VT_I4;
if(gDataType != 0)
{
for(m=0,n=0; n<gDataMaxLength;n++)
{
gData.lVal = ((buffer[m]&0xff)<<24) +
((buffer[m+1]&0xff)<<16) +
((buffer[m+2]&0xff)<<8) +
(buffer[m+3]&0xff);
SafeArrayPutElement(Data->parray,&n,&gData.lVal);
m = m+4;
}
}
else
{
for(n = 0; n<gDataMaxLength; n++)
{
gData.lVal = (long)buffer[n];
SafeArrayPutElement(Data->parray,&n,&gData.lVal);
}
}
break;
case VT_ARRAY|VT_INT://以整型数组接收
gData.vt = VT_INT;
if(gDataType != 0)
{
for(m=0,n=0; n<gDataMaxLength;n++)
{
gData.intVal = ((buffer[m]&0xff)<<24) +
((buffer[m+1]&0xff)<<16) +
((buffer[m+2]&0xff)<<8) +
(buffer[m+3]&0xff);
SafeArrayPutElement(Data->parray,&n,&gData.intVal);
m = m+4;
}
}
else
{
for(n = 0; n<gDataMaxLength; n++)
{
gData.intVal = (int)buffer[n];
SafeArrayPutElement(Data->parray,&n,&gData.intVal);
}
}
break;
case VT_ARRAY|VT_UI1://以BYTE数组接收
gData.vt = VT_UI1;
for(n = 0; n<gDataMaxLength; n++)
{
gData.bVal = buffer[n]&0xff;
SafeArrayPutElement(Data->parray,&n,&gData.bVal);
}
break;
default://其它类型,请各位看官自行实现处理,嘿嘿
delete[] buffer;
return -3;//无法识别传入的数据类型
}
}
else
{
delete[] buffer;
return 0;//网络数据读取超时
}
VariantClear(&gData);
delete[] buffer;
return len;
更多精彩
赞助商链接