Reputation: 2860
As seen in various other posts, I have added a few text files as resources in a Visual Studio 2013 project in the following way: After right-clicking on the project and selecting Add -> Resources I added the following lines to the generated file resource.h
:
#define MY_TEXTFILE 256
#define MY_CONFIG_FILE_RELEASE 4313
#define MY_CONFIG_FILE_DEV1 4314
#define MY_CONFIG_FILE_DEV2 4315
Then, I added the following lines to the .rc
file:
MY_CONFIG_FILE_RELEASE MY_TEXTFILE "configFiles/releaseConfig.properties"
MY_CONFIG_FILE_DEV1 MY_TEXTFILE "configFiles/devConfig.properties"
MY_CONFIG_FILE_DEV2 MY_TEXTFILE "configFiles/dev2Config.properties"
The content of those files is just simply one line, e.g. for the devConfig.properties
it would be
# DEV1 CONFIG
To test the loading mechanism, I use the following directly within main
int main(int argc, char *argv[]) {
const char* data = NULL;
loadTextFileResource(MY_CONFIG_FILE_DEV1, data);
return 0;
}
where the loadTextFileResource
is the following:
bool loadTextFileResource(int inName, const char*& outData) {
HMODULE _handle;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)&someFunction, &_handle);
if (_handle == NULL) return false;
HRSRC _rc = FindResource(_handle, MAKEINTRESOURCE(inName), MAKEINTRESOURCE(MY_TEXTFILE));
if (_rc == NULL) return false;
HGLOBAL _rcData = LoadResource(_handle, _rc);
if (_rcData == NULL) return false;
LPVOID _rcDataLocked = LockResource(_rcData);
if (_rcDataLocked == NULL) return false;
DWORD _size = SizeofResource(_handle, _rc);
if (_size == 0) return false;
outData = static_cast<const char*>(_rcDataLocked);
std::cout << "Loaded: " << outData << std::endl;
return true;
}
The output of this little program is:
Loaded: # DEV1 CONFIG
P# DEV2 CONFIG
PADPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADD
INGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADD
INGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADD
INGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADD
INGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING
Note that the two lines in the beginning are the content of not only MY_CONFIG_FILE_DEV1
but also MY_CONFIG_FILE_DEV2
even though I only requested the former. The same happens when I request to load MY_CONFIG_FILE_RELEASE
(i.e. all three files are loaded into outData
). So it seems that somehow all "subsequent" resources are loaded together with the one I'm requesting. What is going on here exactly and why is my loadTextFileResource
function not doing what I'm expecting, namely load only the content of the resource I'm requesting?
Also: What is the "P" doing in front of "#DEV2 CONFIG" (which is the content of the respective file)? Should I somehow clean the data that was loaded?
Note that this loading mechanism should also work if the project is compiled as a DLL.
Upvotes: 0
Views: 43
Reputation: 513
You assume that the text file data is zero-terminated by assigning the pointer to the beginning of the resource to the const char *
:
outData = static_cast<const char*>(_rcDataLocked);
Basically, you don't use the size
at all. All you need is to construct the string (std::string
or std::wstring
depending on the encoding used by your original text files):
std::string result = { static_cast<const char *>(_rcDataLocked), size };
or
std::wstring result = { static_cast<const wchar_t *>(_rcDataLocked), size / sizeof(wchar_t) };
Upvotes: 1