gpt4 book ai didi

c++ - 如何从 dll 中获取没有垃圾的字符串?

转载 作者:行者123 更新时间:2023-11-28 05:15:03 25 4
gpt4 key购买 nike

我想从 VB 中的 dll 中获取一个字符串,所以我编写了如下代码,

#include <windows.h> 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <tchar.h>
#include <atlconv.h>
#include <atlcoll.h>
#include <assert.h>
#include <atlbase.h>

using namespace std;

double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len)
{
char buff[128];
char * str0;
char str1[128];


*dataout0 = *datain0 + 20;
*dataout1 = *datain1 + 30;

*str_len = 30;

str0 = " Nice ";
sprintf(buff, "Hi %s \n", str0);
strcpy(str1, buff);

char* p = str1;
SysReAllocString(str, (OLECHAR*)p);



return 0;
}

但特别是,在这种情况下,当我证明 s 时,我得到了一个包含垃圾数据的字符串,如下所示。

那么我怎样才能得到没有这些垃圾数据的字符串呢?

: s : Hi Nice 儆儆儆儆儆儆儆儆좄* : String

最佳答案

您在滥用 SysReAllocString() .

您的缓冲区在声明时未初始化,因此它们最初包含堆栈中已存在的任何随机字节。 sprintf()strcpy()然后用有效的 8 位数据填充缓冲区并以 null 终止它们,这在处理 8 位字符串时很好。但是它们不会覆盖空终止符之后的任何内存,因此那里仍然有随机字节。

然后您将按原样将最终的 8 位字符串数据提供给 SysReAllocString() , 使用 char* 的简单类型转换指向 wchar_t* 的指针使编译器满意的指针。但是您仍然指向 8 位数据。 SysReAllocString()需要一个正确的 16 位 Unicode 字符串,包括一个 16 位空终止符。由于您只有一个 8 位空终止符,因此该函数最终会通过您的空终止符复制到周围的内存中。

如果您摆脱类型转换,代码将无法编译,这是有充分理由的。不要使用类型转换来避免编译器错误。

用零预初始化缓冲区只会掩盖问题,方法是确保最终缓冲区中有连续的空字节,这些字节在解释为 16 位数据时可以充当 Unicode 空终止符。但是您仍然在缓冲区中存储 8 位字符数据。

要正确解决此问题,您必须先将输出字符串数据转换为 Unicode,然后才能创建 BSTR从它。

您需要:

  • 使用 MultiByteToWideChar()转换你的最终 char数据到wchar_t .

    double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len)
    {
    char c_buff[128] = {0};
    wchar_t w_buff[128] = {0};
    char * str0;
    int len;

    *dataout0 = *datain0 + 20;
    *dataout1 = *datain1 + 30;

    *str_len = 30;

    str0 = " Nice ";
    len = sprintf(c_buff, "Hi %s \n", str0);

    len = MultiByteToWideChar(CP_ACP, 0, c_buff, len, w_buff, 128);

    SysReAllocStringLen(str, w_buff, len);

    return 0;
    }
  • 重写代码以使用swprintf()而不是 sprintf() .

    double _stdcall pll_dll(double* datain0, double* datain1, double* dataout0, double* dataout1, BSTR * str, int* str_len)
    {
    wchar_t buff[128] = {0};
    wchar_t * str0;
    int len;

    *dataout0 = *datain0 + 20;
    *dataout1 = *datain1 + 30;

    *str_len = 30;

    str0 = L" Nice ";
    len = swprintf(buff, L"Hi %s \n", str0);

    SysReAllocStringLen(str, buff, len);

    return 0;
    }

关于c++ - 如何从 dll 中获取没有垃圾的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42849095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com