Reputation: 581
I have a badly designed DLL library header that use TCHAR
in its header as a struct member*:
struct A {
int nType;
TCHAR szData[128];
};
And also there's a DLL function that passed struct A**
as an argument to return a dynamic allocated array of type struct A
and its length:
void func(int *pnCount, struct A **ppArray);
Since in the DLL library, we use Multi-Byte Character Set in the project setting, TCHAR
is char
.
But in the application, we set Unicode Character Set, and TCHAR
is actually wchar_t
.
Since for some reason, I can not modify the header file, how can I call this DLL function without violating the rules?
Does strict aliasing rule applied across library boundary? I think compiler can not do fancy optimizations on this DLL interface.
If I define the struct on my own (without including the header) in my application project as:
struct A {
int nType;
char szData[128];
};
void func(int *pnCount, struct A **ppArray);
It looks like I didn't violate any rule including strict aliasing rule, doesn't it?
struct A2 {
int nType;
char szData[128];
};
3a. It looks like I need to use some kind of casts to archive this, which of them should I use?
3b. Or can I forward declare the DLL function or dynamically load the DLL function with another signature?
void func(int *pnCount, struct A2 **ppData);
*The following is just simplified example of my real case.
Update:
After reading walnut's answer I realized this may related to one-definition-rule of the standard rather than strict aliasing rule so I changed the title.
Also, to make it's more specific, I remove the C tag.
Upvotes: 0
Views: 380
Reputation: 22152
For C++ from a standards point-of-view (given the language-lawyer
tag). In practice you can get away with much more:
- Does strict aliasing rule applied across library boundary? I think compiler can not do fancy optimizations on this DLL interface.
Yes, it does. However, you are not actually asking anything about the strict aliasing rule, as far as I can tell. Your questions seem to rather be about the one-definition-rule.
- If I define the struct on my own (without including the header) in my application project as:
Yes, that is completely fine, as long as the token sequence (after macro replacement) is exactly the same as in the header used to build the library.
- Since I must include the header, can I use another struct name without violating strict aliasing rule or other rules?
No, you cannot. You would be declaring a different type and a different function and accessing A2
through a pointer to A
(or the other way around) would be undefined behavior.
Additionally, inclusion of the original header (without guarding it in some way so as to not include the mismatching definition) would already cause the program to violate the one-definition-rule and therefore have undefined behavior.
- What about if the usage is not across library boundary, but only across source files (translation units)?
The same answers. The standard doesn't know a difference between the two. It only refers to translation units.
Upvotes: 1