2012-04-13 4 views
0

간단한 질문에 memmove() 및 memcpy(), 내가 그것을 사용하고 memmove() 및 memcpy() 문제가 있습니다. 나는 정말로 내 코드에 무슨 문제가 있는지 이해하지 못한다. 그런데 QT를 사용합니다.QT (C++)

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; 
     } 
    } 
} 
+0

당신이에 대한 자세한 명시한다면 그것은 도움이 될 것입니다 무엇을 너는 묻고있어. 소스 코드에 "항상 오류가 있습니다."라고 말한 주석이 있습니다. 오류가 무엇인지 정확히 알려주고 (오류 메시지가 있습니까?) 소스 코드가 아닌 질문에 해당 정보를 제공하십시오. 감사. –

+0

특히, 코드를 컴파일 할 때 또는 실행할 때 오류가 발생합니까? –

+0

디버깅 할 때 "세그먼트 오류"SIGSEGV 메시지가 있습니다. – user1276647

답변

1

hMapView은 포인터가 아닙니다. memmove에는 두 개의 포인터가 필요합니다. hMapView를 적절하게 선언하여이 문제를 해결하십시오. LPVOID이어야합니다.

+0

또한 선언을 LPVOID hMapView로 변경했습니다. 항상 동일한 오류 메시지가 발생합니다. "세분화 오류"SIGSEGV. – user1276647

0

QT를 사용하는 방식.

예를 들어 실제로 사용하지 않았습니다. Qt에는 QFile::map 메서드가 있으며, 플랫폼 별 MapViewOfFile 대신에 (내 의견으로는) 사용해야합니다.

+1

정말 그 질문에 대한 답변입니까, 아니면 코멘트 여야합니까? –

+0

@KeithThompson : 당신이 내 대답을 싫어하면, 직접 작성하십시오. 한 줄의 코드 대신 3-deep 레벨'if '를 사용하는 것은 비생산적입니다. – SigTerm

+0

당신은 훌륭한 충고를 제공하고 있을지도 모른다. (필자는 MapViewOfFile 또는 QFile :: Map으로 충분히 익숙하지 않다.) 나는 이것이 OP가 요구하는 질문에 대한 직접적인 대답이라는 것을 확신하지 못했습니다. OP는 "이 코드에서 오류가 발생하는 이유는 무엇입니까?" 문제를 진단하고 더 나은 해결책을 제시 할 수 있다면 큰 도움이 될 것입니다. –

1

MapViewOfFileINVALID_HANDLE_VALUE (-1)이 아닌 오류가있는 경우 NULL (0)을 반환합니다.

편집 : 코드와 다른 많은 문제가 발생했습니다

  • QString::constData() 반환 QChar*하지 wchar_t*, 당신은 대신 QString::utf16()을 사용해야합니다.
  • CreateFileMappingW이 실패하면 INVALID_HANDLE_VALUE이 아닌 NULL을 반환합니다.
  • MapViewOfFile 액세스 매개 변수는 FILE_MAP_READ이 아니라 GENERIC_READ입니다.
  • uint은 2 바이트보다 큰 경우가 많으므로, 2 바이트 만 읽으면 memmove 전에 변수를 0으로 초기화해야합니다. 여기

은 (단지 wineg 테스트 ++/와인) 작업을해야 최소한의 코드입니다 :

#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(); 
    } 
} 
+0

QFile :: map()으로 파일을 매핑하는 방법을 모르겠다. 그러나 예제 코드가 있습니다. QFile 파일 ("foo"); file.open (QFile :: ReadOnly); uchar * memory = file.map (0, file.size()); if (memory) { // 데이터를 재미있게 가지고 있습니다. file.unmap(); } – user1276647

+0

@ user1276647 내 대답을 편집했습니다 – alexisdm

+0

그것이 효과가 있습니다! 굉장해! 고마워 친구... – user1276647