LoadString, статическая библиотека и исполняемые файлы - PullRequest
3 голосов
/ 01 февраля 2010

Мой проект настроен так, что весь код и модули фреймворка скомпилирован в статический .lib (назовем его framework.lib), и многие тестовые проекты используют framework.lib и компилируют в исполняемые файлы.

Для обработки ошибок я пытаюсь поместить строки ресурсов в framework.rc (часть проекта framework.lib) и загрузить строки в исполняемые файлы. Однако LoadString() просто терпит неудачу. Используя GetLastError() / FormatMessage(), я получаю следующее сообщение:

"Указанный тип ресурса не найден в файле изображения."

Вот как я называю LoadString, который возвращает 0:

char szString[256];  
int iNbOfChars = LoadStringA(GetModuleHandle(NULL), iStringID, szString, 256);

Должно ли то, что я делаю, быть неудачным, потому что ресурс определен не в приложении, а в lib? Если да, какие-либо предложения, чтобы я мог иметь централизованный файл ресурсов?

Ответы [ 5 ]

3 голосов
/ 01 февраля 2010

Статические библиотеки - это просто конкатенации файлов .OBJ - у них нет таких функций, как ресурсы Для этого вам нужно поместить ресурсы в DLL.

1 голос
/ 01 февраля 2010

Нельзя помещать ресурсы в файлы .lib. (Надеюсь ты мог бы). Вы должны хранить файлы .rc и включать их в файл .rc приложения, когда ссылаетесь на lib.

И поэтому вы должны убедиться, что ни один из идентификаторов ресурсов, используемых .lib, также не используется приложением. Это полный беспорядок, но лучшего решения нет, если вы используете .rc файлы для своих строк. и придерживайтесь инструментов Microsoft.

Примерно пару лет назад я так расстроился из-за этого ограничения, что ушел и создал инструмент, который превратил бы скомпилированный файл ресурсов (.res) в файл .obj, чтобы я мог включить его в свою библиотеку. Конечно, когда вы делаете это, вы больше не можете использовать LoadString, но оказывается, что написание собственного кода для анализа фрагмента данных .res и поиска строк не так уж сложно. Поэтому мое текущее решение для размещения строк в библиотеках -

  • create framework.rc
  • скомпилируйте его в framework.res
  • превратить framework.res в framework.obj, который содержит внешние символы

    const BYTE framework_res[]; const size_t framework_res_size;

  • использовать MyLoadString(framework_res, framework_res_size, iStringId, sz, 256) вместо LoadString при извлечении строк в библиотеке.

Одним из преимуществ такого способа оказалось то, что когда я писал свою собственную LoadString, я мог возвращать указатель на строку ресурса, а не копировать ее. поэтому моя настоящая функция LoadString выглядит следующим образом.

LPCWSTR MyFindString(framework_res, framework_res_size, iStringId);

Если вы скомпилируете ваш файл .rc с параметром / n, он завершит все строки пустым значением.

0 голосов
/ 01 февраля 2010

Очевидным способом централизации ресурсов было бы создание библиотеки DLL, содержащей ресурсы. Затем вы можете использовать LoadString и так же, как если бы ресурс был в исполняемом файле, за исключением незначительных деталей, которые вам нужно указать правильный дескриптор модуля вместо NULL.

0 голосов
/ 01 февраля 2010

AFAIK вы не можете добавлять ресурсы в статическую библиотеку - вы должны либо скомпилировать их в DLL для совместного использования, либо непосредственно в приложение.

Вы можете поделиться .rc из центрального расположения и скомпилировать его в само приложение.

0 голосов
/ 01 февраля 2010

Вы можете использовать директиву #include в файле ресурсов приложения, чтобы включить файл ресурсов библиотеки.

Ресурсы разрешены только на уровне вывода (EXE) и не могут быть встроены в .Lib.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...