views:

39

answers:

1

Why does Visual Studio sometimes turn SAME pointer parameters in COM libraries into uint and sometimes to ulong? I have a COM library that has some methods with parameters such as

[ in ] ULONG_PTR ParentWindow

When I reference this library on my desktop computer, the interop assembly turns the ULONG_PTR into uint. When I do the same on my laptop, it is turned into ulong. This causes problems when sharing the project between machines. I probably could store the Interop assembly in SVN together with rest of the project, but this causes problems if I ever need to regenerate it after updating the COM library for example.

The systems are:

Desktop                                Laptop
- Windows Vista Professional 64-bit    - Windows 7 Ultimate 64-bit
- Visual Studio 2008 Professional      - Visual Studio 2008 Team System
  (SP1)                                  Development Edition (SP1)
- .Net Framework 3.5 SP1               - .Net Framework 3.5 SP1

UAC is enabled and Visual Studio is run as administrator.

I'll try applying Visual Studio 2008 SP1 on the Laptop in case this has any effect.

Edit: Applied SP1 on laptop with no effect.

Update:

When adding the reference to the COM library in Visual Studio, Process Monitor shows devenv reading COMLibrary.dll on the desktop computer while it reads COMLibrary64.dll on laptop. This definitely is the reason why desktop shows uint for pointers while laptop shows ulong.

Now why does it do this? Devenv process on both computers is running under WoW64.

When running the program, it uses COMLibrary64.dll on both computers according to Process Monitor. So the problem seems to be only during the reference adding.

Will try to do the interop generation manually next.

+1  A: 

Is it definitely the same COM server, and not 32 vs 64-bit versions? What you describe has all the hallmarks of targeting different bitnesses, as you probably know - ULONG_PTR is 32 bits in 32-bit compilation targets and 64 bits in 64-bit compilation targets, but native code must be either one or the other at compile time.

The notional "correct" translation would be UIntPtr, but that would float depending on what framework the .NET client process is running, rather than what's required, the bitness of the COM server.

Barry Kelly
Yes it definitely sounds like the difference comes from 32 vs 64-bit versions. Updated the original post slightly now that I figured out how to confirm this. Still have no idea why the difference.
Mikko Rantanen
Oh, and I think (U)IntPtr would be correct in any case. These parameters are mostly window handles and at least WinForms controls expose Handle property as IntPtr. Now I just need to figure out how to tell that to tlbimp.
Mikko Rantanen
COM is a binary standard. The COM interface cannot float between 32-bit and 64-bit depending on which .NET framework was used to execute it, but .NET code will. You should only use U/IntPtr if your executable is fixed to one or the other (i.e. not AnyCPU).
Barry Kelly
Hum. A bit late reply, had a discussion with the COM library developers - they have two versions of the COM library: 32-bit and 64-bit. Their 32-bit installer refuses to install on 64-bit machine and the 64-bit installer installs both versions of the COM library. This results in 32-bit OS and 32-bit processes running under WoW64 always accessing 32-bit COM library while 64-bit processes always use the 64-bit COM library. Doesn't this result in floating pointer lengths from .Net point of view?
Mikko Rantanen