kafman
kafman

Reputation: 2860

Loading of textfile resource in Visual Studio loads more than it should

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

Answers (1)

Alexander Bessonov
Alexander Bessonov

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

Related Questions