[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

Trying to use unmanaged with C#

Steven Edison

2/8/2007 2:32:00 PM

Hi,

My company has a large library of COM objects we've been using for years,
it's massive,
re-writing would take months to years.

One of these objects has a method that looks something like this:

HRESULT EnumItems(IUnkown* pUnk, VARIANT Param);

The IUnknown is a callback, where you would have done something like this:

class CCallback : public ICallbackInterface
{
//Implement dummy Release and AddRefs, supply a good
QueryInterface()

HRESULT MyCallback(LONG ValueNeeded1, BSTR ValueNeeded2, VARIANT
Param)
{
//do something with supplied information
return S_OK;
}
//...
};

CCallback* pCb = new CCallback;
pObj->EnumItems((IUnknown*)pCb, this);

internally it Queries for ICallbackInterface and feeds data to the callback.

Now I need to use this in my C# ASP.NET site. So I made something like
this:

//ref COM obj and convert to managed dll.
using System.Runtime.InteropServices;
using MyObjLib;

[ComVisible(true)] //added with no difference after getting error
public class CallbackClass : CallbackInterface
{
public void MyCallback(int ValueNeeded1, string ValueNeeded2, object
Param)
{
//deal with it
}
};

CallbackClass cc = new CallbackClass;
pObj.EnumItems(cc, this);

and I get this:

**Exception Details: System.InvalidOperationException: This type has a
ComVisible(false) parent in its hierarchy, therefore QueryInterface calls
for IDispatch or class interfaces are disallowed.

pointing to my Enum function. What am I doing wrong? and how can I use
this interface in C# correctly?

Thanks for any help!

Steven


7 Answers

Patrick Steele

2/8/2007 2:46:00 PM

0

In article <eLbTd34SHHA.920@TK2MSFTNGP05.phx.gbl>,
EdisonCPP@newsgroups.nospam says...
> Hi,
>
> My company has a large library of COM objects we've been using for years,
> it's massive,
> re-writing would take months to years.
>
> One of these objects has a method that looks something like this:
>
> HRESULT EnumItems(IUnkown* pUnk, VARIANT Param);
>
> The IUnknown is a callback, where you would have done something like this:
>
> class CCallback : public ICallbackInterface
> {
> //Implement dummy Release and AddRefs, supply a good
> QueryInterface()
>
> HRESULT MyCallback(LONG ValueNeeded1, BSTR ValueNeeded2, VARIANT
> Param)
> {
> //do something with supplied information
> return S_OK;
> }
> //...
> };
>
> CCallback* pCb = new CCallback;
> pObj->EnumItems((IUnknown*)pCb, this);
>
> internally it Queries for ICallbackInterface and feeds data to the callback.
>
> Now I need to use this in my C# ASP.NET site. So I made something like
> this:
>
> //ref COM obj and convert to managed dll.
> using System.Runtime.InteropServices;
> using MyObjLib;
>
> [ComVisible(true)] //added with no difference after getting error
> public class CallbackClass : CallbackInterface
> {
> public void MyCallback(int ValueNeeded1, string ValueNeeded2, object
> Param)
> {
> //deal with it
> }
> };
>
> CallbackClass cc = new CallbackClass;
> pObj.EnumItems(cc, this);

Did you also mark the assembly as COMVisible? Check out your
AssemblyInfo.cs.

--
Patrick Steele
http://weblogs.asp.n...

Steven Edison

2/8/2007 3:01:00 PM

0

I'm afraid my .NET "greenness" may be hendering me here,
but my ASP.NET application doesn't seem to have a
AssemblyInfo.cs, and the original object was written in
unmanaged C++, so it wouldn't have one either. The assembly
was created just by referencing an existing C++ COM DLL
in my new C# app. Could you point me to which AssemblyInfo.cs
you're referring to?

Thanks!

> Did you also mark the assembly as COMVisible? Check out your
> AssemblyInfo.cs.
>
> --
> Patrick Steele
> http://weblogs.asp.n...


Steven Edison

2/8/2007 3:32:00 PM

0

Looking back, I probably didn't clarify very well that
the origianl COM obj is unmanaged, and I'm trying
to use it in a managed environment.


Patrick Steele

2/8/2007 8:01:00 PM

0

In article <uLirTZ5SHHA.3592@TK2MSFTNGP06.phx.gbl>,
EdisonCPP@newsgroups.nospam says...
> Looking back, I probably didn't clarify very well that
> the origianl COM obj is unmanaged, and I'm trying
> to use it in a managed environment.

Sorry Steve. Looking back at your original post, I do see that you're
consuming a COM object, not trying to create one in .NET. Sorry about
that.

However, as part of the COM interface, do you need to pass a reference
of a .NET object to COM? And you're doing this from an ASP.NET app?

First off, I'm no ASP.NET expert, but I think you might have some
security issues running a COM object from inside ASP.NET since COM is
unmanaged. I think the default security for ASP.NET is to not allow
unmanaged execution of code.

Second, if you *do* need to pass a reference of some .NET class to a COM
object, then you'll need to make sure your assembly which contains this
class is marked as COM visible. It looked like you made your class COM
Visible via the ComVisible attribute, but the assembly (the "parent" in
the hierarchy defined in the error message) defaults to COM visible
false.

What I would do is create a class library that does what you need
(interact with the COM object) and get that debugged and working outside
ASP.NET. Then just add a reference to that class library inside your
ASP.NET application once everything is working.

--
Patrick Steele
http://weblogs.asp.n...

Steven Edison

2/8/2007 8:38:00 PM

0


"Patrick Steele" <patrick@mvps.org> wrote in message
news:MPG.20354b8b5589ecee9896ee@msnews.microsoft.com...
> In article <uLirTZ5SHHA.3592@TK2MSFTNGP06.phx.gbl>,
> EdisonCPP@newsgroups.nospam says...
>> Looking back, I probably didn't clarify very well that
>> the origianl COM obj is unmanaged, and I'm trying
>> to use it in a managed environment.
>
> Sorry Steve. Looking back at your original post, I do see that you're
> consuming a COM object, not trying to create one in .NET. Sorry about
> that.
>
> However, as part of the COM interface, do you need to pass a reference
> of a .NET object to COM? And you're doing this from an ASP.NET app?
>

It only became the need to be a .NET object when I "imported" it into my
managed app. Originally it was a pointer to an IUnknown implemented
class instance that would be a callback. Yes, it is ASP.NET.
The actual object is a front end for communications with a server app.
The object houses all the protocol for clients. So instead of sending
all the socket protocol to login you can simply:
pObj->Authenticate(name, pword);
And then ask questions of the server app:
pObj->GiveMeAllTheseItems((IUnkwown*)pWhereToSendResults,
PassThruPointer/*so you can do something with results*/);

The new site needs talk to this server, and the historical way we've talked
to it through numberous apps, is this COM object. The methods house
very lengthy protocol and error checking, that are proven and solid.

> First off, I'm no ASP.NET expert, but I think you might have some
> security issues running a COM object from inside ASP.NET since COM is
> unmanaged. I think the default security for ASP.NET is to not allow
> unmanaged execution of code.

Would you think this still be an issue since when I referenced it - it
created a
managed dll like: bin/Interop.MyLib.dll?
BTW, it seems up until this callback the COM object is operating correctly.
I can:
pObject.Connect(IP, port);
pObject.Authenticate(name, pword);
//etc..
It's just when the COM object tries to QueryInterface() internally on
the class instance I created within C# that it throws an exception.

>
> Second, if you *do* need to pass a reference of some .NET class to a COM
> object, then you'll need to make sure your assembly which contains this
> class is marked as COM visible. It looked like you made your class COM
> Visible via the ComVisible attribute, but the assembly (the "parent" in
> the hierarchy defined in the error message) defaults to COM visible
> false.

How can I make it be ComVisible(true) when it converts it to a managed
assembly?

>
> What I would do is create a class library that does what you need
> (interact with the COM object) and get that debugged and working outside
> ASP.NET. Then just add a reference to that class library inside your
> ASP.NET application once everything is working.
>

I'll give this a try. Create a managed class library assembly that
references
the comm object? Then reference this new assembly in a test app, but
eventually
in the ASP.NET pages? It would strike me that very quickly I will run into
the
same Query problems with the callback implementation.

The end goal is to ask an unmanged C++ Windows Service questions, get
answers,
and have it do things. The unmanaged COM object can do this now, wrapping
all the lengthy protocol and error checking.

> --
> Patrick Steele
> http://weblogs.asp.n...


wawang

2/9/2007 7:56:00 AM

0

Hi Steven,

I also suggest first to create a non-ASP.NET project to test your COM
callback interface; due to ASP.NET dynamic compilation model.

How's your CallbackInterface defined? Does it inherit from IUnknown or
IDispatch? It would be great if you could send me some reproducible code of
your COM component so that I can verify the behavior on my side.



Sincerely,
Walter Wang (wawang@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default....
ications. If you are using Outlook Express, 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/de....
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Patrick Steele

2/9/2007 9:00:00 PM

0

In article <urxUOE8SHHA.3996@TK2MSFTNGP04.phx.gbl>,
EdisonCPP@newsgroups.nospam says...
> > First off, I'm no ASP.NET expert, but I think you might have some
> > security issues running a COM object from inside ASP.NET since COM is
> > unmanaged. I think the default security for ASP.NET is to not allow
> > unmanaged execution of code.
>
> Would you think this still be an issue since when I referenced it - it
> created a
> managed dll like: bin/Interop.MyLib.dll?

Yes, because "Interop.MyLib.dll" is just a wrapper assembly. It really
just contains .NET metadata that describes the type of
objects/methods/parameters of the COM object it's wrapped.

The COM object is still going to need to be registerd on the machine.
Your "interop" assembly just defines a way for the .NET interop layer to
talk to an existing COM object.

And when it comes to running it, the interop layer knows it's running
unmanaged code and will stop if the permissions aren't correct.

> > Second, if you *do* need to pass a reference of some .NET class to a COM
> > object, then you'll need to make sure your assembly which contains this
> > class is marked as COM visible. It looked like you made your class COM
> > Visible via the ComVisible attribute, but the assembly (the "parent" in
> > the hierarchy defined in the error message) defaults to COM visible
> > false.
>
> How can I make it be ComVisible(true) when it converts it to a managed
> assembly?

See above. It's not a conversion -- it's just a wrapper. And wrapper
is probably a bad term since it implies the existing COM object is
"wrapped inside" the wrapper. Not true. It's more of a "COM to .NET"
dictionary for a particular COM library that .NET uses when it needs to
talk to COM (sitting in between COM and .NET).

--
Patrick Steele
http://weblogs.asp.n...