0

I'm converting what were formerly separate DLL and EXE modules of an MFC application (that is itself based on combining two disparate codebases) into static library (LIB) projects. I took steps to ensure that resource IDs are all unique, but I'm getting a linker error claiming there's duplicate string resources when it links the .res files compiled from different projects' .rc files.

Thing is, the resource ID's the linker says are duplicate do not match any of my resource ID's in use. I figured out by trial and error (and the reported "size" which does match the string resource) that, for each string, the ID being used for the string table resource does not match the one defined by the constant from Resource.h. It's "semi" deterministic in that if, e.g., 3646 gets mapped to 228 then 3647 will be compiled as 229, however the basis value is different for different compilation units, and there seems to be a modulo applied too.

You can see these values by adding the /v (verbose) option in the resource compiler properties page for the project.

That is, if A is the string ID value from Resource.h, what the resource compiler will actually write to the .res file, B, seems to be something like:

B = (A - x) mod y

For some unknown x and y. It might not actually even be modulus; I can't pin it down.

WTF is going on here? Somehow loading the string resource still finds the resource at runtime (assuming linking was successful), but it causes conflicts on linking two different .res files because of the different basis (x) or modulo (y) results in B having the same value for different A.

Actual output from compiler (using /v arg to resource compilation step):

1>Writing AFX_DIALOG_LAYOUT:3508,   lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:3606,   lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:84, lang:0x409, size 2.
1>Writing AFX_DIALOG_LAYOUT:3502,   lang:0x409, size 2.............................................................................................
1>Writing STRING:227,   lang:0x409, size 278
1>Writing STRING:228,   lang:0x409, size 190
1>Writing STRING:229,   lang:0x409, size 302
1>Writing STRING:231,   lang:0x409, size 740

In the above, 3508, 3606, 84, and 3502 are actual dialog ID values. Based on definitions of the symbols from Resource.h the string resources should be ID's numbering above 3000, not in the 200s. (The sizes match & I can prove it's that string by adding/removing characters and the size reported changes.) The same thing happens when I put literal numeric values in the .rc file instead of using macros from Resource.h.

2
  • 1
    String table resources get grouped together into buckets of 16. See this, look for "String resources are stored in sections of up to 16 strings per section". What the linker sees is those sections, not individual strings. The section ID is simply string ID divided by 16 (maybe plus 1, to avoid having ID 0). Commented Mar 7 at 21:16
  • 1
    The format of string resources. Commented Mar 7 at 21:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.