[omniORB] Byte order inversion on NT/MSVC++

Sai-Lai Lo S.Lo@orl.co.uk
14 Dec 1998 16:58:35 +0000


Dietmar,

omni::myByteOrder is defined in omniORB261_rt.dll and it must have the
__declspec(dllimport) attribute attached when your code is compiled.
This is normally done by the CPP macro _OMNIORB_NTDLL_IMPORT (in
CORBA_sysdep.h).

First thing to check is whether when your code is compiled,
the CPP macro _OMNIORB_NTDLL_IMPORT is defined as __declspec(dllimport).

I have a strong suspicion that you either:

   1. Have not defined the three CPP macros that are *required*
        -D__x86__ -D__NT__ -D__WIN32__

or 2. Have -D_OMNIORB2_DLL defined (which should only be defined when
      building the runtime)

or 3. Have -D_WINSTATIC defined but still link with the DLL.

So it is best to check what the value of _OMNIORB_NTDLL_IMPORT is when your
code is compiled. If it is not __declspec(dllimport) then the end result is 
that all reference to omni::myByteOrder in your code/stub will be directed
to a local copy rather than the DLL.

Regards,

Sai-Lai



>>>>> Dietmar May writes:

> I've run into a problem with byte order inversion within a server on Windows
> NT 4 (sp3) compiling with MS VC++ 5.0 (sp3).

> Enums are causing marshalling errors, because the op<== (unsigned long) is
> reversing the byte ordering when unmarshalling values - 0x00000004 becomes
> 0x04000000, etc. Same thing happens for doubles, 1.0 becoming 3.2e-316 or
> some such value.

> The unmarshalling code (NetBufferedStream::operator<==()) performs a
> comparison of RdMessageByteOrder() with omni::myByteOrder. In my case,
> RdMessageByteOrder() yields 1, while omni::myByteOrder is 255. There seems
> to be a flaw in the code here that should be fixed, since it is performing a
> boolean comparison using two unsigned char values; hence, if both of these
> are non-zero, but not equivalent, omniORB inverts the byte ordering of data
> in the input stream.

> Another strange behavior I've noticed is that the address (and data) for
> omni::myByteOrder is different when I set a breakpoint in my application
> code than when I put the breakpoint in omniORB DLL code. If I create a
> static initializer object within constants.cc and break in the constructor
> (during the runtime initialization sequence), I can view the address and
> data of omni::myByteOrder, and it looks reasonable (including being
> initialized to 1).

> If I debug through the rest of the runtime initialization, it looks fine
> UNTIL it returns from executing DllMain(). The address of omni::myByteOrder
> changes at this instant (as viewed in the DevStudio watch window), and its
> value changes to 255. However, the data at the original (omniORB DLL)
> address of myByteOrder remains unchanged (at 1). The new address of
> omni::myByteOrder (with value 255) is the address inside the map file of the
> application.

> I've tried compiling and linking with 2.5.1, 2.6.1, creating both stub-DLL
> and stub-linked versions. An earlier version of the application was working.
> The problem is obviously NOT the application randomly overwriting memory,
> since the original memory contents remain unchanged, and since the address
> of myByteOrder suddenly changes when the DLL initialization code completes.
> I suspect some issue with the way that MSVC links static data from DLLs and
> performs its fix-ups, since the results of the link seem to think the
> myByteOrder address is somewhere other than where the omniORB runtime DLL
> thinks it is.

> Any ideas or suggestions would be greatly appreciated.

-- 
Dr. Sai-Lai Lo                          |       Research Scientist
                                        |
E-mail:         S.Lo@orl.co.uk          |       Olivetti & Oracle Research Lab
                                        |       24a Trumpington Street
Tel:            +44 223 343000          |       Cambridge CB2 1QA
Fax:            +44 223 313542          |       ENGLAND