问:关于QT的memmove()和memcpy()(c ++)

时间:2012-04-13 21:02:09

标签: c++ qt winapi memory

简单的问题,当我使用它时,我有memmove()和memcpy()的问题。我真的不明白我的代码有什么问题。顺便说一句,我使用QT。

HANDLE hFile;
HANDLE hMapFile;
HANDLE hMapView;

hFile = CreateFileW((const wchar_t*) objPath.constData(), GENERIC_READ , 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE){

    hMapFile = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hMapFile != INVALID_HANDLE_VALUE){

        hMapView = MapViewOfFile(hMapFile, GENERIC_READ, 0, 0,0);
        if (hMapView != INVALID_HANDLE_VALUE){
            uint DefineWord;
            memmove((void *) &DefineWord, hMapView,2); // <- always error right here
            qDebug()<<DefineWord;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

hMapView不是指针。 memmove需要两个指针。通过正确声明hMapView来解决此问题。它应该是LPVOID

答案 1 :(得分:1)

MapViewOfFile会在出现错误时返回指针或NULL(0),而不是INVALID_HANDLE_VALUE( - 1)。

修改:您的代码存在许多其他问题:

  • QString::constData()返回QChar*,而不是wchar_t*,您必须使用QString::utf16()
  • 如果CreateFileMappingW失败,则返回NULL,而不是INVALID_HANDLE_VALUE
  • MapViewOfFile访问参数为FILE_MAP_READ,而不是GENERIC_READ
  • uint通常大于2个字节,因此如果只读取2个字节,则应在memmove之前将变量初始化为0。

这是一个应该有效的最小代码(仅在wineg ++ / wine上测试):

#include <windows.h>
#include <QtCore/QString>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>

int main(int argc, char const *argv[])
{
    if (argc < 2) {
        QTextStream(stdout) << "Usage :" << argv[0] << " filename" << endl;
        return 1;
    }

    QString objPath(argv[1]);
    // Qt source uses C-Style cast from utf16() to (wchar_t*),
    // so it should be safe
    HANDLE hFile = CreateFileW((const wchar_t *) objPath.utf16(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        qDebug() << qt_error_string(); 
    } else {
        HANDLE hMapFile = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (!hMapFile) {
            qDebug() << qt_error_string(); 
        } else {
            void *pMapView = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
            if (!pMapView) {
                qDebug() << qt_error_string();
            } else {
                uint DefineWord = 0;
                memmove((void *) &DefineWord, pMapView, 2);
                qDebug() << DefineWord;
            }
            CloseHandle(hMapFile);
        }
        CloseHandle(hFile);
    }
    return 0;
}

PS:QString qt_error_string(int errorCode = -1)是一个显然未记录的Qt函数,它返回上一个错误的错误字符串(来自GetLastError()errno返回的错误代码)。

如果您使用的是Qt,则可以使用QFile::map()将文件映射到内存。
要执行初始代码应该执行的操作,您只需要在找到的代码示例中添加2行(加上错误检查):

QFile file("foo"); 
if(!file.open(QFile::ReadOnly)) {
   qDebug() << file.errorString();
} else {
    uchar *memory = file.map(0, file.size()); 
    if (!memory) {
        qDebug() << file.errorString();
    } else {            
        uint DefineWord = 0;
        memmove(&DefineWord, memory, 2);

        file.unmap(); 
    }
} 

答案 2 :(得分:0)

  

我使用QT的方式。

在你的例子中,你并没有真正使用它。 Qt有QFile::map方法,可以(在我看来应该)使用,而不是特定于平台的MapViewOfFile。