Форум программистов, компьютерный форум CyberForum.ru

VC++2010 не могу открыть ресурсы - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
07.12.2013, 17:59     VC++2010 не могу открыть ресурсы #1
Снова обращаюсь к уважаемому обществу. На этот раз проблема такая (VS2010 Professional, консольное приложение).
Включил текстовый файл .txt в ресурсы. Написал такой доступ к нему (ниже). Однако никак такой код не хочет находить мой ресурс, сразу уходит на сообщение "Ресурс не найден". Т.е. функция FindResource возвращает не имя ресурса, а NULL.
Что надо сделать, чтобы ресурс был найден и можно было читать данные из текстового файла?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <clocale>
#include <strsafe.h>
 
// == Пробная Функция открытия текстового файла ресурса и чтения строк и символов из него ======
 
char ShtReadDATAFromFile()
{
    std::setlocale(LC_ALL, "Russian_Russia.1251");   // Устанавливаем русский шрифт для окна консоли
 
    HRSRC hShtDataTXT = NULL;      // Определяем и инициализируем переменную ресурса
    char buf[75] = {0};                  // Определяем и инициализируем нулями сроку длиной 75 символов    
    
    HMODULE hModule = NULL;
    LPCTSTR IpName = "IDR_TEXT1";
    LPCTSTR IpType = "TEXT";
    hShtDataTXT = FindResource(hModule, IpName, IpType);  // Ищем файл ресурса. Получаем указатель на ресурс
 
    if(hShtDataTXT!=NULL)         // Если указатель не равен нулю 
    {
        std::cout <<  "Ресурс найден!" << "\n" << std::endl;
        HGLOBAL  hShtAirportsRes = NULL;   // Определяем и инициализируем переменную для работы с другими функциями
        hShtAirportsRes = LoadResource(0, hShtDataTXT);  // Загружаем и открываем файл ресурса 
        if(hShtAirportsRes!=NULL)
        {
            LPVOID res = LockResource(hShtAirportsRes);         // Фиксируем наш файл в памяти, для чего передаем указатель HGLOBAL.
                                                                // Приводим к типу const char* и работаем с указателем как со строкой, хранящей все содержимое файла
            DWORD dwSize = SizeofResource(0, hShtDataTXT);      // Определяем размер нашего текстового файла
            char *t = (char* )res;
            
            std::ifstream  AirportDATA("ShtProba.txt");    // Объявляем объект AirportDATA типа ifstream и открываем текстовый файл ресурса для вывода данных
            std::cout <<  "Файл открыт!" << "\n" << std::endl;
 
            AirportDATA.getline(buf, 75, 0);                  // Считываем первую строчку
            std::cout <<  "A:  " << AirportDATA.getline(buf, 75, 0)  << std::endl;
            return buf[1];
        }
        else
        std::cout <<  "Файл не открыт!" << "\n" << std::endl;
           return NULL;                // Если файл не открыт, возвращается 0 по умолчанию
    }
    else
        std::cout <<  "Ресурс не найден!" << "\n" << std::endl;
        return NULL;            // Если ресурс не найден, возвращается 0 по умолчанию
}
 
// Главная программа С++
//--------------------------------
int __cdecl _tmain(int argc, _TCHAR* argv[])
{
    ShtReadDATAFromFile();
 
    std::system("Pause");               // Предотвращение закрытия консольного окна
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:16     VC++2010 не могу открыть ресурсы #21
Цитата Сообщение от kotgav Посмотреть сообщение
Открыл свой текстовый ресурс в проекте, в конце дописал \0. И сохранил это изменение.
Почерпнул этот прием из учебника: Прохоренок Н.А. Глава 6 Символы и строки стр.20. (на первом скрине выдержка из учебника).
Указывал и без кавычек, и в кавычках символ \0 выводится как обычный символ.
На скрине, разве '\0' добавляется в текстовом редакторе (как вы сделали)? Когда вы в текстовом редакторе пишите '\0', то это не терминальный ноль (управляющий символ), а просто четыре символа. Терминальный ноль существует в языке, в коде, (в редакторе его нет), и использовать его можно только методами языка. Например, строковые функции чтения из файла добавляют его в конец строки. В файл, терминальный ноль, можно записать в бинарном режиме, т.е., открыть файл для дозаписи в конец файла (ios::app), и, в бинарном режиме, записать туда переменную char, со значением 0:
C++
1
2
3
4
5
fstream f("file.txt", ios::app);
char ch = 0;
f.write((const char*)&ch, 1);
 
f.close();
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
11.12.2013, 17:26  [ТС]     VC++2010 не могу открыть ресурсы #22
Вот какой код в результате получился:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void ShtReadDATAFromFileRes()
{
    std::setlocale(LC_ALL, "Russian_Russia.1251");        // Устанавливаем русский шрифт для окна консоли
 
    /*Получаем хэндл модуля (исполняемого файла, *.exe или *.dll), в котором лежит ресурс.
    NULL означает модуль, ассоциированный с текущим процессом, хотя возвращен будет не ноль, а хэндл модуля.
    При работе с текущим модулем можно сразу вызывать FindResource, передавая первым параметром NULL, а под VCL можно использовать глобальную HInstance*/
    HMODULE hModS = GetModuleHandle(NULL);
    std::cout << "hModS:   " << hModS << std::endl;    // Вызываем в консоль для проверки
 
    HRSRC hShtDataTXT = NULL;            // Определяем и инициализируем переменную ресурса
 
    // Определяем указатели имени и типа ресурса
    wchar_t const *pResName = MAKEINTRESOURCEW(115); // Номер в resource.h
    wchar_t const *pResType = MAKEINTRESOURCEW(10);  // RT_RCDATA для текстового файла
    
    // Производим поиск ресурса
    HRSRC const hResInfo = FindResourceW(hModS, pResName, pResType);
    if (NULL == hResInfo)
    {
        std::cout << "Ресурс не найден!" << std::endl;
        return;  // Если ресурс не найден, возвращается 0 по умолчанию, выход из программы
    }
    
    // Определяем размер ресурса
    DWORD const ResSize = SizeofResource(NULL, hResInfo);
    if (0 == ResSize)
    {
        std::cout << "Размер ресурса не определен!" << std::endl;
        return;  // Если размер ресурса не определен, возвращается 0 по умолчанию, выход из программы
    }
 
    // Загружаем ресурс в память
    HGLOBAL const hRes = LoadResource(NULL, hResInfo);
    if (NULL == hRes)
    {
        std::cout << "Ресурс не загружен!" << std::endl;
        return;  // Если ресурс не загружен, возвращается 0 по умолчанию, выход из программы
    }       
 
    // Получаем указатель на ресурс, как на строку. Читаем его
    VOID const *pResData = LockResource(hRes);
    if (NULL == pResData)
    {
        std::cout << "Ресурс не читается!" << std::endl;
        return;  // Если ресурс не читается, возвращается 0 по умолчанию, выход из программы
    }           
            std::string Str;
            std::string TextFromResource;
            TextFromResource.append(static_cast<char const *>(pResData), static_cast<DWORD>(ResSize));
 
            std::cout << "dwSize:  " << ResSize << "\n" << std::endl;
            std::cout << "TXTFile:  " << "\n" << TextFromResource << std::endl;
}
Результат показан на скрине консольного окна, файл читается правильно.
Миниатюры
VC++2010 не могу открыть ресурсы  
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
11.12.2013, 17:30  [ТС]     VC++2010 не могу открыть ресурсы #23
Цитата Сообщение от alsav22 Посмотреть сообщение
На скрине, разве '\0' добавляется в текстовом редакторе (как вы сделали)? Когда вы в текстовом редакторе пишите '\0', то это не терминальный ноль (управляющий символ), а просто четыре символа. Терминальный ноль существует в языке, в коде, (в редакторе его нет), и использовать его можно только методами языка. Например, строковые функции чтения из файла добавляют его в конец строки. В файл, терминальный ноль, можно записать в бинарном режиме, т.е., открыть файл для дозаписи в конец файла (ios::app), и, в бинарном режиме, записать туда переменную char, со значением 0:
C++
1
2
3
4
5
fstream f("file.txt", ios::app);
char ch = 0;
f.write((const char*)&ch, 1);
 
f.close();
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:44     VC++2010 не могу открыть ресурсы #24
Цитата Сообщение от kotgav Посмотреть сообщение
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
Да.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
11.12.2013, 17:50  [ТС]     VC++2010 не могу открыть ресурсы #25
Понятно.
Убежденный и alsav22!
Большое Вам спасибо за помощь!
Вопрос с открытием и чтением ресурса решен.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.12.2013, 17:51     VC++2010 не могу открыть ресурсы #26
Цитата Сообщение от kotgav Посмотреть сообщение
А, так файл надо было просто открыть, не как ресурс? И тогда его откорректировать функциями работы с открытым файлом? А потом закрыть и снова открыть и читать как файл ресурса?
Но это, если очень нужно именно через терминальный ноль в конце файла (некое извращение). Если есть другой способ, то лучше его использовать.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
22.12.2013, 12:22  [ТС]     VC++2010 не могу открыть ресурсы #27
Возвращаюсь к проблеме чтения ресурса.
Мне надо, чтобы ресурс хранился в библиотеке. Там же происходит некоторая обработка, связанная с чтением ресурса. На основе примера в сообщении #22 я сделал функцию чтения текстового ресурса, подключил к библиотеке ресурс и скомилировал файл *.dll.
Из исполняющей exe программы я обращаюсь к библиотеке и хочу увидеть значение одного из параметров ресурса.
Библиотека и библиотечная функция чтения ресурса отыскиваются нормально, параметр HMODULE hModS имеет не нулевое значение, параметры функции
HRSRC const hResInfo = FindResourceW(hModS, pResName, pResType);
тоже имеют ненулевые значения, т.е. функция нахождения текстового ресурса FindResourceW должна завершиться с ненулевым значением. А она возвращает 0!
Т.е. ресурс на находит.
В то же время, если я подключаю ресурс также и в исполняющую программу, то ресурс библиотечная функция находит и открывает исправно.
В чем может быть дело?
Мне надо хранить ресурс именно в библиотеке.

Добавлено через 11 минут
Дополнение.
Если точнее описать задачу, то мне надо иметь две библиотеки.
Одна - с текстовыми файлами ресурсов.
Другая - с функциями обработки тестовых файлов ресурсов, из которой вызывается первая библиотека.
А уже исполняющая программа вызывает вторую библиотеку.
Т.е. такая пирамида получается:
исполняющая программа -> библиотека2 -> библиотека1(с ресурсами).
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
24.12.2013, 14:58  [ТС]     VC++2010 не могу открыть ресурсы #28
Еще дополнение.
Попробовал открывать текстовый файл (не ресурс) через библиотеку с помощью std::ifstream, open() и прочих функций открытия текстового файла.
Не Открывает!
Может быть С++ в принципе не может работать с файлами-ресурсами и текстами через библиотеку?
Если так, то грустно!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.01.2014, 15:24     VC++2010 не могу открыть ресурсы
Еще ссылки по теме:

C++ vs 2010 выдает ошибку fatal error C1083: Не удается открыть файл включение: ntddcdrm: No such file or directory
C++ Не могу открыть программу на других компьютерах
C++ Не могу открыть файл через argv[]

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
19.01.2014, 15:24  [ТС]     VC++2010 не могу открыть ресурсы #29
Для тех, кто столкнется с такой же проблемой.
Напомню, что мне надо было использовать ресурс, находящийся в текстовом файле и включенный в библиотеку DLL №1. В свою очередь, доступ к библиотеке DLL №1 должен быть из библиотеки DLL №2. А уже доступ к библиотеке DLL №2 должен быть из исполняющего файла. Т.е. цепочка доступа к ресурсу такая:
исполняющая программа -> библиотека №2 -> библиотека №1(с ресурсами).
Открытие файла ресурса, который находится в библиотеке №1, через библиотеку № 1, долго не мог произвести и вот наконец добился положительного результата.
Причина оказалась простой - соглашение о вызовах!
Это соглашение о вызове функции для доступа к библиотеке и ресурсам (у меня оно extern "C" __declspec(dllexport) ) было записано только в библиотеке №1. А во второй библиотеке написать забыл. Поэтому доступ к библиотекам был, а доступа к функциям, и соответственно - к ресурсам, не было.
Теперь все работает, ресурс через две библиотеки открывается и читается.
Yandex
Объявления
19.01.2014, 15:24     VC++2010 не могу открыть ресурсы
Ответ Создать тему
Опции темы

Текущее время: 11:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru