【问题标题】:Trash characters when using buffers in c++在 C++ 中使用缓冲区时的垃圾字符
【发布时间】:2013-07-30 11:32:03
【问题描述】:

我有一个需要用 C++ 处理的 DLL。我正在使用 WxWidgets(标准编译,但我也尝试过 Unicode 开/关)和 NetBeans。我也尝试在没有 WxWidgets (windows.h) 的情况下处理这个问题并且遇到了同样的问题。

这是我使用 WxWidgets 访问 DLL 函数的方法:

// -------------------- POINTERS TO FUNCTIONS
typedef bool(*TYPE_DLL_SetLicense)(char*, char*);
typedef bool(*TYPE_DLL_PingConnection)(char*); 
typedef char*(*TYPE_DLL_ERR_DESCRIPTION)(void);

class DLL_Library
{
public:
    // pointers to functions inside dll
    TYPE_DLL_SetLicense DLL_SetLicense;        //initialize - will wor fine as it returns only true/false (buffer only provide data)
    TYPE_DLL_PingConnection DLL_PingConnection;      //ping to serwer. Will return trahs, becouse it uses buffer to provide data ang get answear back
    TYPE_DLL_ERR_DESCRIPTION DLL_ERR_DESCRIPTION;      //error description. No buffer, no trouble. Returns correct string.
    wxDynamicLibrary dynLib2;

    int initialize(void)
    {
        //patch to dll
        wxString path = wxStandardPaths::Get().GetExecutablePath().BeforeLast('\\') + _("\\DLL_dll\\DLLMOK.dll");
        if(!wxFile::Exists(path)) return -1;

        //load dll
        if(!dynLib2.Load(path)) return -2;

        //Assign functions in dll to variable
        DLL_SetLicense=(TYPE_DLL_SetLicense) dynLib2.GetSymbol(wxT("DLL_SetLicense"));
        DLL_PingConnection=(TYPE_DLL_PingConnection)  dynLib2.GetSymbol(wxT("DLL_PingConnection"));
        DLL_ERR_DESCRIPTION=(TYPE_DLL_ERR_DESCRIPTION) dynLib2.GetSymbol(wxT("DLL_ERROR_DESCRIPTION"));


    return 0;
   }
};

这是我运行的函数。它应该返回和 XML 内容,我尝试将其保存到文件中。

//DLL_PingConnection            
//result ping to be save in file
wxFile file_ping_xml;
plik_ping_xml.Open(wxT("C:\\dll\\ping.xml"),wxFile::write);
char buffor_ping_xml[2000];

//I run the function here
bool is_ping = DLL_PingConnection(buffor_ping_xml);

if(is_ping)
{

    tex_box->AppendText(wxT("DLL_PingConnection True\n"));

    //we save result to file
    bool is_write_ping_ok = file_ping_xml.Write(buffor_ping_xml,2000);
    if (is_write_ping_ok){tex_box->AppendText(wxT("Save to file is ok ok\n"));}
    else {tex_box->AppendText(wxT("Save to file failed :( \n"));}                
}
else
{
    tex_box->AppendText(wxT("DLL_PingConnection False\n"));
} 


std::cout << "Error description: " << DLL_ERR_DESCRIPTION() << "\n"; //will work fine both in saving to file, and in streaming to screen.

问题是在文件内部而不是好的内容我得到这样的垃圾:

请注意,这只发生在使用以下缓冲区的函数中:

char buffer[2000] //buffer will contain for example file xml
function do_sth_with_xml(buffer) //buffer containing xml will (should) be overwriten with xml results of the function - in our case DLL_PingCONNECTION should save in buffer xml with connection data

文档说 DLL 在 Windows-1250 上运行。文件ping.xml我已经设置为windows ANSI,但我认为问题不在这里。

编辑:我在没有 WxWidgets 的情况下编写了问题(我使用 windows.h 加载 DLL)——同样的问题。这是代码:Getting trash data in char* while using it as buffer in function。请帮忙:(

【问题讨论】:

    标签: c++ arrays file char


    【解决方案1】:

    这个

    DLL_PingConnection=(TYPE_DLL_PingConnection)
    

    不应该

    DLL_PingConnection=(TYPE_DLL_PingConnection) dynLib2.GetSymbol(wxT("DLL_PingConnection"));
    

    ?

    否则您将无法获得指向 DLL 中函数的有效指针。

    作为一般规则,您应该检查返回值,尤其是来自 DLL 您会动态加载,因为有时您会获得另一个版本 可能具有相同名称但其他签名的函数的 DLL 或 哪里完全不见了。

    【讨论】:

    • 我的错。我编辑了我的问题。 PS:我确实检查了 dll 函数的返回值。我得到了 succec (bool -> true) 但在缓冲区中我发现只有垃圾,而返回字符串而不是 bool 的函数(不使用缓冲区)工作得很好。示例是 DLL_ERR_DESCRIPTION
    【解决方案2】:

    你命名了一个函数

    DLL_PingConnection=(TYPE_DLL_PingConnection) dynLib2.GetSymbol(....
    

    并用

    调用它
    OSOZ.OSOZ_PingConnection(buffor_ping_xml);
    

    你 typedef 一个函数

    typedef bool(*TYPE_DLL_PingConnection)(char*); 
    

    你创建一个变量

    char buffor_ping_xml[2000];
    

    在你的 typedef 中它是 char* 而你的 buffor_ping_xml 是 char

    这怎么行?

    试试

    char *buffor_ping_xml = new char[2000]; 
    /* or */
    wchar_t *buffor_ping_xml = new wchar_t[2000];
    /* or */
    wxChar *buffor_ping_xml = new wxchar[2000];
    
    bool is_ping = DLL_PingConnection(buffor_ping_xml);
    wxString mystring = wxString::FromUTF8(buffor_ping_xml);
    

    mystring 写入文件。

    待办事项:

    • 在您的wxwidgets\libs 文件夹中查找您的libs libwxmsw29ud_* 的名称中是否有 'u'(此处为版本号 29)? 如果不是 你不能使用 unicode

    如果是,下一步

    • 对于所有不同的测试char *wchar_t *wxChar *,请给文件不同的名称。
      例如 file_ping_xml.Open(wxT("C:\dll\ping_w_t_FromUTF8.xml"), ...
      对于 wchar_t * 结合
      wxString mystring = wxString::FromUTF8(buffor_ping_xml);
    • 也可以与
    • 结合使用
    • wxString mystring(buffor_ping_xml);

    • 然后在浏览器中查看文件的外观。

    要进行测试,您可以转到 wxWidgets 示例文件夹。在文件夹 C:\wxWidgets\samples\docview\docview.cpp 中编译。用 docview.exe 打开一个 unicode 文件。看起来怎么样。

    Unicode download file

    Unicode 相关的编译设置

    您应该将wxUSE_UNICODE 定义为1 以在Unicode 模式下编译您的程序。这目前适用于 wxMSW、wxGTK、wxMac 和 wxX11。如果您在 ANSI 模式下编译程序,您仍然可以定义 wxUSE_WCHAR_T 以获得对 wchar_t 类型的有限支持。

    【讨论】:

    • 嗨。函数名称是错字(现已修复) - 我删除了一些代码以使其更易于阅读。然而,关于变量buffor_ping_xml[2000],如果我像这样给出 bufor,这是唯一可行的方法:char * buffor_ping_xml 程序将崩溃。在文档中,我有一个要使用的数据类型PChar。有什么想法吗?
    • 另外:从 typdef 中去掉 * 将无法编译。
    • @baron_bartek:你试过了吗:const char *buffor_ping_xml = new char[2000];
    • 感谢您的想法。我将 typedef 更改为 typedef bool(*TYP_OSOZ_PingConnection)(const char*); 并使用了 const char *buffor_ping_xml = new char[2000]; 它已编译,但我仍然收到垃圾。您还确定函数能够更改 const char 吗?抱歉,我是 C++ 的新手
    • 这个答案是完全错误的。数组衰减为指针。这是语言的一部分。所以buffor_ping_xml的定义是兼容char*参数的。
    【解决方案3】:

    这里是回复:Getting trash data in char* while using it as buffer in function

    感谢大家 - 特别是耐心。

    【讨论】:

      猜你喜欢
      • 2021-11-28
      • 1970-01-01
      • 2016-08-17
      • 2020-06-08
      • 1970-01-01
      • 2023-03-26
      • 2014-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多