On Mon, 04 Apr 2011 08:13:09 -0700, Keith Thompson <kst-u@mib.org>
wrote:
>DSF <notavalid@address.here> writes:
>> I have a situation where I have two structures that are identical
>> except for the names. A simplified example:
>>
>> struct foo
>> {
>> unsigned long a;
>> unsigned long b;
>> };
>>
>> struct bar
>> {
>> unsigned long a;
>> unsigned long b;
>> };
>>
>> I don't have the ability to re-designate either of them, as they
>> each belong to a different library.
>>
>> So if I need to pass a function in library "foo" a "bar" variable, I
>> must create a "foo" variable and copy each member from the "bar"
>> variable to it. This is not my idea of efficiency.
>>
>> I figure the answer's one of two things: It's either something I've
>> missed/forgotten, or it can't be done and I'm SOL.
>
>It might be helpful to have some more information about the actual
>structures. (I presume they aren't really called "foo" and "bar".)
>
>You've shown us two struct types with exactly the same members
>(same member names and types). Do these two libraries really
>declare identical types? Are they certain to remain identical in
>future versions of both libraries? Is the layout of both structures
>imposed by some external interface?
See below.
>
>Why does it make sense to pass a "bar" variable to a function in the
>"foo" library?
Ditto.
>
>"Data, data, data! I cannot make bricks without clay!"
What I posted above is not the exact situation, it's a watered-down
example.
Here is the full story.
The reason I did not post the actual structure data is that there
are a host (as in large number) of sacred cows in this group one must
not go around tipping, and there is a host (as in army) of people
ready to textually rip you a new one if you tip a cow or two. :o)
The supine bovine here is that the answer I was looking for need not
be portable, so I decided to use a generic example. In reality, the
first "library" is actually part of Windows and the second is my own.
The Windows "struct" is defined as:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
DWORD = unsigned long.
LONG = long.
LONGLONG (see below).
Oops. It's a union. The above is from the WINNT.H file. My Windows
API help file defines it as a structure. With a little more checking,
MS's site has this comment:
"The LARGE_INTEGER structure is actually a union. If your compiler has
built-in support for 64-bit integers, use the QuadPart member to store
the 64-bit integer. Otherwise, use the LowPart and HighPart members to
store the 64-bit integer."
To make matters even stranger, the LONGLONG above that defines
QuadPart is a typedef of double on my system. Although it's the same
number of bits as two longs, I don't believe anything other than zero
in both LowPart and HighPart will be represented correctly in
QuadPart. So I just ignore it and use the LowPart and HighPart.
My structure is defined as:
typedef struct tag_int64 {
unsigned long ldw;
unsigned long hdw;
} int64;
You might be asking why I just didn't use MS's LARGE_INTEGER for my
library. The main reason would be that I'd written the library at a
time where I wasn't using any MS API calls that used LARGE_INTEGER.
Another reason was that it just didn't match my style of programming.
I prefer my variable names to be all lower case, and in the case of
structure members, short. Having to deal with something like:
void foo(unsigned long startl, unsigned long starth);
LARGE_INTEGER count;
Then later,
foo(count.u.LowPart, count.u.HighPart);
isn't a good fit for me.
When I realized that I was going to be dealing with a lot of MS API
calls that use LARGE_INTEGER, I started looking for a better solution
than copying the individual members.
Sorry to be so long winded, but that's the whole story.
Ben Bacarisse's suggestion of a union works perfectly. I use:
typedef union tag_li64 {
int64 i64;
LARGE_INTEGER li;
} li64;
li64 count;
and use count.li for the MS API
and count.i64 for mine.
DSF
P.S. Yes, I know that the high 32 bits of LARGE_INTEGER are signed
whilst they are unsigned for int64. It's not a concern for what I'm
doing.