2012-04-18 1 views
0

Я повторно использую старый код (изначально разработанный на c, а не C++) с некоторыми функциями для открытия/чтения/управления текстовыми файлами. Путь к текстовым файлам передается функциям в виде строки (char *), затем открывается с использованием: FileToUse = fopen(filename, "rb");, затем используются несколько вызовов fread() и fseek(). Этот код, как известно, работает для внешних текстовых файлов, но теперь я хотел бы включить текстовые файлы в качестве ресурсов в свой проект (MFC C++ в visual studio).Ресурс вместо внешнего файла C++

Я нашел несколько примеров в Интернете о том, как использовать rusulting ресурсы в этом коде:

HINSTANCE hInst = AfxGetResourceHandle(); 
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(IDR_TEXTFILE1), "TEXTFILE"); 

if (hResource){ 
    HGLOBAL hLoadedResource = LoadResource(hInst, hResource); 
    if (hLoadedResource){ 
    const char* pResource = LockResource(hLoadedResource); 
    if (pResource){ 
     DWORD dwResourceSize = SizeofResource(hInst, hResource); 
     if (0 != dwResourceSize){       // if(FileToUse){ 
     memcpy(&Buffer, pResource, (15 * 2));    // fread($Buffer, 15, 2, FileToUse); 
     pTemp = pResource + 200;       // fseek(FileToUse, 200, SEEK_SET); 
     pTemp = pTemp + 100;        // fseek(FileToUse, 100, SEEK_CUR); 
     pTemp = pResource + (dwResourceSize - 1) - 40;  // fseek(FileToUse, -40, SEEK_END); 
     } 
    } 
    } 
} 

Я заменил Fread вызов тетсру(), как показано на рисунке, но я пропускаю возвращаемое значение FREAD (фактические прочитанные элементы), а в исходном коде filepointer был перемещен fseek, интересно, правильно ли мой подход с использованием временного указателя.

Моя конечная цель состоит в том, чтобы смоделировать Fread и FSEEK вызовы на ресурсы с аналогичными прототипы функций:

size_t resread(void* buffer, size_t size, size_t count, char* resource);

int resseek(char* resource, long offset, int origin);

Любые предложения очень ценятся.

+0

Этот вопрос, кажется, полностью зависит от конкретного окна. Вы должны добавить такой тег. – bjhend

+0

@bjhend Код загрузки ресурсов загрузки зависит от Windows, но он уже получил это право. Вопрос в том, чтобы дублировать fread, так что он не агностик. –

ответ

2

Спасибо за вашу помощь, основанный по предложению Agent_L в этом то, что я придумал:

типа Text-ресурсов:

struct _resource { 
    const char * content;  // File content 
    size_t size;    // File size 
    size_t ptrloc;    // 'Pointer' location 
}; 
typedef struct _resource RES_TXT; 

resread на основе FREAD:

size_t resread(void* buffer, size_t size, size_t count, RES_TXT * resource) 
{ 
    size_t actualCount = (resource->size - resource->ptrloc)/size; 
    actualCount = min(count, actualCount); 
    if (actualCount <= 0) return 0; 
    memcpy(buffer, (resource->_ptr + resource->ptrloc), (actualCount * size)); 
    resource->ptrloc += (actualCount * size); 
    return actualCount; 
} 

и завершить resseek на основе FSEEK:

int resseek(RES_TXT * resource, long offset, int origin) { 
    size_t nextloc; 
    switch (origin) { 
     case SEEK_SET: nextloc = 0; 
      break; 
     case SEEK_CUR: nextloc = resource->ptrloc; 
      break; 
     case SEEK_END: nextloc = resource->size; 
      break; 
     default: return -1; 
    } 
    nextloc += offset; 
    if (nextloc >= 0 && nextloc < resource->size) 
     resource->ptrloc = nextloc; 
    else 
     return -1; 
    return 0; 
} 

Любой вызов FSEEK и Fread теперь можно заменить использовать ресурс вместо внешнего файла.

1

Ручка файла содержит не только данные, но также длину и текущее положение. Вы должны дублировать это. (handwirtten код, недоказанным):

struct resFile 
{ 
    char* pData; 
    int iLenght; 
    int iCurrPosition; 
}; 

size_t resread(void* buffer, size_t size, size_t count, resFile* resource) 
{ 
    int ActualRead = min(size*count, resource->iLenght - resource->iCurrPosition); 
    memcpy(buffer, resource->pData + resource->iCurrPosition, ActualRead); 
    resource->iCurrPostion += ActualRead; 
    return ActualRead; 
} 
+0

Хорошая точка, это также означает, что можно было бы поместить указатель данных ресурса в элемент данных стандартной структуры FILE (_iobuf). Однако я должен был бы определить других участников ресурса. Я рассмотрю точные элементы структуры и их функции. – Apprecreate

+0

О, не путайся с этим. ФАЙЛ имеет фактическое имя файла и дескриптор открытого файла, и Билл знает, что происходит внутри фактического fread. Перепрофилирование fread и fseek очень просто. В C++ вы можете перегружать fopen, fread и fseek, поэтому потребуется только изменение FILE в resFile. Или, возможно, вы даже можете уйти с #define FILE resFile. –

+0

Я заметил, что возвращаемое значение для fread не является байтом, но число фактических блоков, считанных (bytecount 'size'), см. Мой принятый ответ для кода. – Apprecreate

0

Позвольте мне предупредить вас, что fread изменения текущей позиции файла. Это означает, что вам не нужно вызывать fseek каждый раз. С этой точки зрения может быть ваш код может избежать реализации resseek путем простого увеличения Buffer указатель

+0

Мне было известно, что файл-указатель сдвинут по fread, но fseek, например, также используется как check: if (fseek (FileToUse, (вычисление следующей позиции), 0) == -1) return ERROR; – Apprecreate