【问题标题】:Qt throws error with working code when in its own binaryQt 在其自己的二进制文件中引发工作代码错误
【发布时间】:2019-11-29 06:37:27
【问题描述】:

我自己编写了这个程序,它工作正常,但是当作为头文件导入到 Qt 项目时,它会抛出一个错误,而代码原本可以工作。 错误:

这是头文件

#include <iostream>
#include <string>
#include <sstream>

//global vars
FILE *pFile;
char * buffer;
long lSize;

std::basic_stringstream<char> e_lfanew() {
pFile = fopen("hello.exe", "r");

//get file size
fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);

//alloc memory
buffer = (char *) malloc(sizeof(char) * lSize);

//read file to memory
auto result = fread(buffer, 1, lSize, pFile);

auto e_lfanew = (unsigned char *) malloc(4);
fseek(pFile, 0x3c, SEEK_SET);
fread(e_lfanew, 0x1, 0x4, pFile);
std::stringstream pe_offset;
for(size_t i=0; i<4; i++){
    std::cout << std::hex << (int)e_lfanew[i];
    pe_offset << std::hex << (int)e_lfanew[i];
}
std::cout << pe_offset.rdbuf();

return pe_offset;
}

这是 qt mainwindow.c 文件(具有导致错误的按钮按下功能的文件)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "e_lfanew.h"

 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
     , ui(new Ui::MainWindow)
 {
     ui->setupUi(this);
 }

 MainWindow::~MainWindow(){
     delete ui;
 }

 void MainWindow::on_pushButton_clicked(){
     QString e_lfanew_value = QString::fromStdString(e_lfanew().str());
     ui->label_2->setText(e_lfanew_value);
 }

【问题讨论】:

  • 小心。它不是来自Qt 的二进制文件。它来自kernel。因此,我认为问题出在e_lfanew函数
  • 为什么不使用fstream 而不是使用fopen 打开文件,或者如果您要在项目中使用Qt,请使用QFile
  • 如果fopen() 失败,您将获得nullptr。用nullptr 调用fseek() 可能对你失败的assert() 有好处。 (不确定,但很确定。)您确实应该始终测试文件打开是否成功,尤其是对于 C 文件 API。
  • 顺便说一句。在 MS Windows 上,应始终明确地读取二进制文件:fopen(file_name, "rb")(或std::ifstream(file_name, std::ios::binary))。否则,您可能无法获得文件中真正拥有的内容。 ;-)

标签: c++ qt


【解决方案1】:

您的程序不会从Qt 二进制文件而是从minkernel/crts/ucrt/src/appcrt/stdio/fseek.cpp 引发错误。因此,当您尝试fseek 时,我认为问题出在您的代码上。你的代码有一些问题,一个很大的问题是你在使用之前没有检查文件描述符不为空。

您可以阅读来自fopen() 的文档。

如果文件成功打开,该函数返回一个指向FILE 对象的指针,该对象可用于在未来的操作中识别流。 否则,返回一个空指针。 在大多数库实现中,errno 变量也会设置为系统特定的失败错误代码。

这意味着您可能会在打开文件后在pFile 变量中获得一个空指针。尝试添加以下行。

std::basic_stringstream<char> e_lfanew() {
pFile = fopen("hello.exe", "r");

if (pFile == nullptr)          // or simply if (!pFile)
    // Cannot open file. Handle the situation

fseek(pFile, 0, SEEK_END);
long lSize = ftell(pFile);
rewind(pFile);

编辑 1

正如评论中提到的@Scheff,在 MS Windows 上,应始终明确地读取二进制文件:fopen(file_name, "rb") (or std::ifstream(file_name, std::ios::binary))。否则,您可能无法完全了解文件中的内容。

【讨论】:

    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    相关资源
    最近更新 更多