如何在C语言中将wchar_t转换为BYTE*

4

我希望将一个wchar_t变量转换为BYTE *,然后通过流发送。

我的代码如下:

wchar_t val[] = L"abc";

我尝试使用以下方式进行转换:

BYTE * bytes = (BYTE *)val;

在读取字节时,我不能读取所有的字符,只能读取第一个字符 - "a"

我认为,我没有很好地转换 wchar_t

我做错了什么?

编辑:

static void DASH_process_receive(rdpSvcPlugin* plugin, wStream* data_in)
    int bytes;
    wStream* data_out;
    DASHPlugin* DASH = (DASHPlugin*) plugin;

    fprintf(stderr, "DASH_process_receive:\n");

    if (!DASH)
    {
        fprintf(stderr, "DASH_process_receive: DASH is nil\n");
        return;
    }

    /* process data in (from server) here */
    /* here we just send the same data back */

    bytes = Stream_Capacity(data_in);
    fprintf(stderr, "DASH_process_receive: got bytes %d\n", bytes);


       wchar_t val[] = L"abc";
       bytes = Stream_Capacity(data_in);

    if (bytes > 0)
    {

        fprintf(stderr, "size wcslen val  %zd\n", wcslen(val));

        fprintf(stderr, "size of val  %zd\n", sizeof(val)); //I Have 16

        data_out = Stream_New((BYTE*)val, sizeof(val));


        Stream_Copy(data_out, data_out,sizeof(val));

        /* svc_plugin_send takes ownership of data_out, that is why
           we do not free it */

        bytes = Stream_GetPosition(data_out);
        fprintf(stderr, "DASH_process_receive: sending bytes %d\n", bytes);

        svc_plugin_send(plugin, data_out);
}

    Stream_Free(data_in, TRUE);
}

编辑:读取数据

WTSVirtualChannelRead(VirtChannelParamsStart, 20000, (PCHAR)Message, sizeof(Message), &ulBytesRead))

unsigned short Message[1024];
CString paramsPourStarter;
paramsPourStarter = Message;
SetDlgItemText(IDC_ED_DASH_RESU,paramsPourStarter);
2个回答

6

你是如何读取bytes的长度的?

如果sizeof(wchar_t) == 2(并假设你正在运行小端主机),那么byte指向的数据将如下所示

{'a', '\0', 'b', '\0', 'c', '\0', '\0', '\0'}

因此,strlen 遇到在 'a' 后紧接着的空字符后就会停止计算字符串长度。

当您转换 wchar_t 数组时,还应该使用 wcslen 计算其长度。

BYTE * bytes = (BYTE *)val;
size_t len = wcslen(val) * sizeof(val[0]);
// pass len to any functions which are passed bytes

2
@Pis 如果 sizeof (wchar_t) 是16,我会感到惊讶。sizeof val 可能是16 (sizeof (wchar_t) == 4,而 val 包含4个元素)。val 的前三个元素不为零,所以 wcslen(val) == 3。但是非零的 wchar_t 仍然包含 _0-bytes_,因此普通的字符串处理函数认为它在第一个 wchar_t 的第一个字节后停止。 - Daniel Fischer
@simonc,val[] = L"abc"; 中的 L 是什么意思? - Grijesh Chauhan
1
@GrijeshChauhan指定了一个Unicode(UTF16)字符的字符串文字。有关详细信息,请参见[这里](http://msdn.microsoft.com/en-us/library/dybsewaf.aspx)。 - simonc
你能提供一个完整的示例来展示这个问题吗?在本问题中更新代码或发布一个新问题都可以。发布一个新问题可能会获得更广泛的观众,因为只有我注意到本问题的更新可能性较小。 - simonc
@Pis David Heffrnan已经证明了我之前所说的关于没有人注意到对旧问题的编辑是错误的 :-). 他的答案是,你的消息接收者将其视为char*处理,这听起来是正确的。如果你查看我回答中val的内存表示形式,你就会明白为什么会发生这种情况。 - simonc
显示剩余4条评论

4
铸造是好的,我假设您发送了正确数量的字节。这可以通过sizeof(val)找到,对于您问题中的代码,假设是2字节的UTF-16字符,则相等于8。或者,如果您的是4字节的UTF-32字符,则sizeof(val)将为16。
问题可能在读取数据的代码的另一端。我可以想象三种明显的故障模式:
1. 您未能读取整个缓冲区。也许您认为内容是以空终止的,并且读取到第一个零字节。这是不正确的,因为空实际上是两个零字节。 2. 您已正确读取整个缓冲区,但是将数据解释为而不是。 3. 你已经正确地阅读并将其解释为。但是在发送方为UTF-32,在接收方为UTF-16。这意味着当实际为UTF-32时,您会将数据解释为UTF-16。
以上任何一种说明都可以解释为什么您只收到了第一个字符。
无论如何,我认为您的处理问题方式错误。 您应该避免将UTF-16 / UTF-32传输到网络中。 对于您的文本,面向字节的编码更好,自然的选择是UTF-8。
更新
您的更新使情况更加清晰。 您正在通过网络发送UTF-32数据,但是然后将该数据解释为UTF-16(假设您的Windows程序是Unicode程序)。 这种不匹配会导致数据被错误地解释,并解释为仅接收第一个字符。这是上面第3个故障项。
为了解决这个问题,您需要非常清楚地了解如何编码文本。您所面临的根本问题可以通过您的问题中不谈论文本编码来观察到。如果要在不同程序之间传递数据,则需要达成共识的通用文本编码方式。再次推荐将UTF-8编码的文本放入网络中。
您还有一个问题,即您假定文本以空终止。如果有传输错误,则接收程序有缓冲区溢出。您还需要解决字节顺序的问题。您需要让所有参与方就网线数据达成共识。使用网络字节顺序。

我不知道。这取决于你的编译器。在Windows上,是8,在许多*nix平台上,是16。你仍然希望使用UTF8。 - David Heffernan
我的编译器是Mac OS上的XCODE。 - Pis
你的问题描述了在另一端无法读取数据的故障。你没有展示出你是如何读取数据的,因此我的回答也不够具体。除非你展示出你是如何读取数据,否则我无法提供更多帮助。 - David Heffernan
你展示的远远不够。我们需要看到类型以及你如何显示字符串。 - David Heffernan
好的,现在清楚发生了什么。我已经更新了我的答案。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接