描述:
我在COM中从客户端往服务端传递结构体数据,服务端接收到后,用结构体指针强制转换时得到的Name为乱码。结构体为:
typedef struct POI_Data_Struct
{
double Pointx;
double Pointy;
BSTR Name;
}POI_Data_Struct;
BSTR类型用在结构体中不合适,但是如果是不定长的Name,我该用什么数据类型?char可以用,但是等指定长度。
如果可以用BSTR,该怎么解决乱码的问题?
客户端:
POI_Data_Struct bs;
bs.Pointx=100.1;
bs.Pointy=100.2;
bs.Name=_T("zhangzhi");
BSTR bstr1 = ::SysAllocStringByteLen((char*)&bs, (UINT)sizeof(bs));
long index;
index=0;
BSTR bstr=bstr1;
hr=SafeArrayPutElement(pSa,&index,bstr);
POI_Data_Struct *p=(POI_Data_Struct*)bstr;//此时p->Name能正确显示出“zhangzhi”
服务端:
long j;
j=0;
BSTR bstr1;
::SafeArrayGetElement(p1,&j,&bstr1);
POI_Data_Struct *ps=(POI_Data_Struct*)bstr1;
::MessageBox(NULL,ps->Name, _T("SafeArray Value1:"), MB_OK);
//此时ps->Name显示为乱码
请各位指教。谢谢!
解决方案1:
我觉得你可以用 VARIANT 类型, VARIANT Name, 祝你好运
解决方案2: POI_Data_Struct bs;
bs.Pointx=100.1;
bs.Pointy=100.2;
bs.Name=_T("zhangzhi"); 这里不对,需要申请用SysAllocStringByteLen
这样定义结构:
typedef struct POI_Data_Struct
{
double Pointx;
double Pointy;
CHAR Name[]; // 这个是可变长的,但是不是指针
}POI_Data_Struct;
但是不能直接申请结构变量,比如POI_Data_Struct pd;就是错误的,应该申请一段所需的内存,然后强制转换成此结构:
BYTE* pBuf = new BYTE[sizeof(POI_Data_Struct) + strlen(str) + 1];
POI_Data_Struct* pData = (POI_Data_Struct*)pBuf;
strcpy(pData->Name, str);
pData->Pointx = 10;
pData->Pointy = 20;
BSTR bstr1 = ::SysAllocStringByteLen((char*)pBuf, (UINT)sizeof(POI_Data_Struct) + strlen(str) + 1);
delete[] pBuf;
BSTR相当于一个指针,SafeArrayPutElement的封装只是把地址封装进去了,这样定义你的数据结构:
typedef struct POI_Data_Struct
{
double Pointx;
double Pointy;
OLECHAR Name[256];
}POI_Data_Struct;
_T("zhangzhi"); //对于_T这个宏,只有字符集使用 Unicode的时候才是宽字符串。
客户端、服务端都用 Unicode字符集。
结构里使用BSTR是可以的,也可以用LPWSTR。 并不需要指定长度。