0

簡単な質問ですが、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;
        }
    }
}
4

3 に答える 3

1

MapViewOfFileポインタを返します。NULLエラーが発生した場合は、(-1)ではなくINVALID_HANDLE_VALUE(0)を返します。

編集:あなたのコードには他にもたくさんの問題がありました:

  • QString::constData()を返しますがQChar*、代わりwchar_t*に使用する必要があります。QString::utf16()
  • 失敗した場合は、ではなく、CreateFileMappingWを返します。NULLINVALID_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(); 
    }
} 
于 2012-04-13T21:18:48.820 に答える
1

hMapViewポインタではありません。memmove2 つのポインターが必要です。hMapView を適切に宣言して、これを修正します。である必要がありLPVOIDます。

于 2012-04-13T21:10:22.257 に答える
0

ちなみに私はQTを使っています。

あなたは実際にあなたの例でそれを使用していません。QtにはQFile::mapメソッドがあり、プラットフォーム固有のMapViewOfFileの代わりに使用できます(私の意見ではそうすべきです)。

于 2012-04-13T21:17:46.843 に答える