all groups > dotnet interop > november 2007 >
You're in the

dotnet interop

group:

C#, exposed as COM with pointers as parameters


C#, exposed as COM with pointers as parameters Mark
11/28/2007 2:05:00 PM
dotnet interop:
Hi...

We've got a mix of old legacy code and new versions in various states of
porting being used in our system.

One of the objects ported to C# and then exposed back to the legacy code as
COM takes a pointer as a parameter. The use of the pointer is opaque (kind
of like HANDLE); we're just using it as a unique identifier. Currently in
the interface, this parameter is declared as a uint.

Now we're trying to move to a 64-bit system and are running into all of the
usual 32-to-64 conversion issues.

I thought of changing
[DispId(2)]
void Method(uint id);

to
[DispId(2)]
void Method(IntPtr id);

which I think would give it the compilation flexibility I want.

But I'm not sure how the interop stuff is actually getting translated to
unmanaged apis (I saw one object exposed as com declaring a StringBuilder as
the output for example; got to be some massaging going on there).

Since you can build/run 32- and 64-bit on a 64-bit system, I was wondering
what declaring a COM parameter an IntPtr would do to the object
registration/use? Obviously it would be bad to try and register both
versions on the system.

Thanks
Mark
Re: C#, exposed as COM with pointers as parameters Mark
11/29/2007 6:39:03 AM
Thanks Christian (and Jialiang)...

[quoted text, click to view]

WOW... that does seem counter intuititve... :)

[quoted text, click to view]

What about the interface guids and progids? If I have one project using
IntPtr as the method parameter but with the same progids and guids used
throughout, would regsvr32 sort that out correctly if I built for 32-bit and
64-bit then registered both?

Mark
RE: C#, exposed as COM with pointers as parameters jialge@online.microsoft.com
11/29/2007 8:02:06 AM
Hello Mark,

From your post, my understanding on this issue is: (1) how to make a COM
client works well in both 32bit and 64bit environment and (2) how is IntPtr
translated to unmanaged environment. If I'm off base, please feel free to
let me know.

(1) how to make a COM client works well in both 32bit and 64bit environment
I find a good article that talks about "Accessing 32-bit Dlls from 64-bit
code" http://dnjonline.com/article.aspx?ID=jun07_access3264. As the article
says, 64bit code and 32bit code cannot co-exist in one process. I
reproduced it when I registered a COM object written in C# with 64bit
regasm.exe, and use a 32bit C++ client application to create the COM
object. The 32bit application is not able to create the object and throws
an exception.

The possible workarounds are:
1. As the article http://dnjonline.com/article.aspx?ID=jun07_access3264
says, we could use DCOM, an out-of-process COM component. DCOM is still
supported on 64-bit Windows platforms, so both 32-bit and 64-bit COM
modules can be built. The only limitation is that 64-bit and 32-bit modules
cannot reside in the same process space, so they have to interoperate
across process boundaries.
2. As you said, building 2 versions of the COM DLL may not be a good
resolution, but it can help to resolve the problem indeed. The 32bit
version of COM object is for 32bit clients, and the 64bit version is for
64bit applications.

(2) how is IntPtr translated to unmanaged environment
According to the MSDN article
http://msdn2.microsoft.com/en-us/library/system.intptr(VS.71).aspx, The
IntPtr type is designed to be an integer whose size is platform-specific.
That is, an instance of this type is expected to be 32-bits on 32-bit
hardware and operating systems, and 64-bits on 64-bit hardware and
operating systems. It is translated to "long" in my test C++ client
application and it works well both in both 32bit system and 64bit one.

Please let me know if you have any other concerns, or need anything else.

Sincerely,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
For MSDN subscribers whose posts are left unanswered, please check this
document: http://blogs.msdn.com/msdnts/pages/postingAlias.aspx

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications. If you are using Outlook Express/Windows Mail, please make sure
you clear the check box "Tools/Options/Read: Get 300 headers at a time" to
see your reply promptly.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: C#, exposed as COM with pointers as parameters Christian Fröschlin
11/29/2007 9:54:42 AM
[quoted text, click to view]

The obvious is not always correct ;)

On a 64-bit Windows systems, the registry has a separate area
for 32-bit compatibility stuff (confusingly named WOW64, btw),
so you can indeed register both versions of a COM DLL. The
tool is called regsvr32 in both cases - although you might
need to use the version in SysWOW64 for the 32-bit case.

Which version of the library is loaded depends on whether
Re: C#, exposed as COM with pointers as parameters Christian Fröschlin
11/29/2007 5:38:12 PM
[quoted text, click to view]

You can use the same ids, as they will be registered in separate
portions of the registry and only the appropriate one is visible to
a process. In fact, you *must* use the same IDs because VS 2005 is
itself a 32-bit process and will only "see" the 32-bit COM DLLs.
Thus, a programmer using your DLL will add a reference to the
Re: C#, exposed as COM with pointers as parameters jialge@online.microsoft.com
12/3/2007 3:33:16 AM
Hi Mark,

Would you mind letting me know the result of the suggestions? If you need
further assistance, feel free to let us know. I will be more than happy to
be of assistance.

Have a great day!

Sincerely,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
When responding to posts, please "Reply to Group" via your newsreader
so that others may learn and benefit from your issue.
=================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Re: C#, exposed as COM with pointers as parameters Mark
12/3/2007 8:37:02 AM
Hi Christian...

Okay, so in the C#, I declare the interface as having an IntPtr parameter;
how should I declare a platform-independent invocation in unmanaged code? I
tried using (void*) in the C++ but got compilation errors.

I found the C# interop .tlh file generated from the .tlb declared the IntPtr
parameter as an unsigned long.

Do I need to have a platform-dependent #ifdef in the C++?

Thanks
Mark
Re: C#, exposed as COM with pointers as parameters jialge@online.microsoft.com
12/5/2007 2:25:22 AM
Hello Mark,

32bit client can only consume 32bit COM server;
64bit client can only use 64bit COM server.
If we do not plan to use COM+, we need to have two versions of COM servers
installed, and pass/cast the parameter as 'long', rather than 'void *', in
the client side. I do not think a platform-dependent #ifdef is necessary in
this case.

Regards,
Jialiang Ge (jialge@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

=================================================
When responding to posts, please "Reply to Group" via your newsreader
so that others may learn and benefit from your issue.
=================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Re: C#, exposed as COM with pointers as parameters Mark
12/5/2007 8:38:14 AM
Hi Christian...

I finally got access to the x64 box to try some of this stuff. Turns out
when you have unmanaged c++ consuming a .net COM client using IntPtrs as
parameters, the tlb exposes it as long when compiled 32-bit and as __int64
when compiled x64. I dug up the .tlh both ways.

For the time being, I've just added an #ifdef in my C++ detecting if *it* is
being compiled x64...

Thanks
Mark


[quoted text, click to view]
Re: C#, exposed as COM with pointers as parameters Christian Fröschlin
12/5/2007 9:35:33 AM
[quoted text, click to view]

Hmm ... actually I never tried this way, for me C# was always
the COM client. But even in this case the native COM server had
differing interfaces due to a typedef between long and __int64.
Actually that was not an ideal solution because it means tlbimb
generated different interop libraries for the 32-bit and 64-bit
versions (instead of a single one using IntPtr).

In your case, it seems you would need to somehow get two
different versions of the tlb from your exposed C# class.
You might consider just using "long" in C# and __int64
in C++ even on 32-bit platforms to avoid this and
cast the values instead (on C# side dynamically
AddThis Social Bookmark Button