Hi Jerry,
Normally a wrapper use composition instead of inheritance to hold a
reference to another class, and create some public methods to delegate the
calls into the wrapper class. In the example mentioned in article
(http://msdn2.microsoft.com/en-us/library/ms364069(VS.80).aspx#vbbestprac_to
pic4), the GuidWrapper is not inehriting from .NET Guid, instead, it
creates a public method NetGuid() and delegates the call to Guid.NewGuid().
That is not to say we cannot use inheritance to delegate the calls, you
certainly could create a new method and use "MyBase.Test()" to call into
the base class.
To better understand why inheriting from a .NET class directly doesn't
expose its public interface to COM client, we need to understand what is
the ComClassAttribute attribute doing for you.
The ComClassAttribute attribute instructs the compiler to add metadata that
allows a class to be exposed as a COM object.
Use ComClassAttribute to simplify the process of exposing COM components
from Visual Basic. COM objects are very different from .NET Framework
assemblies; without the ComClassAttribute, you need to follow a number of
steps to generate a COM object from Visual Basic. For classes marked with
ComClassAttribute, the compiler performs many of these steps automatically.
Here's a COM object without using the ComClassAttribute:
Imports System.Runtime.InteropServices
<Guid(ComClass3.InterfaceId)> _
Public Interface IComClass3
Sub Test()
End Interface
<Guid(ComClass3.ClassId)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class ComClass3
Implements IComClass3
Public Const ClassId As String = "decd3406-2c6b-4335-86fe-0fb3ce3ac17c"
Public Const InterfaceId As String =
"4222b51e-b9b7-4305-9c13-3bf2c3f1a56c"
Public Sub Test() Implements IComClass3.Test
End Sub
End Class
This is strictly following COM programming rules: we first define an
interface, then we define a coclass which implements the interface.
Now back to the issue you're seeing: Logging isn't applied
ComClassAttribute, there's no COM interface defined for it, the VB6 client
will not be able to see the public methods defined in it.
I hope this could help you better understand the COM interop. For your
reference, I'm including some good resources on this topic:
#Understanding Classic COM Interoperability With .NET Applications - The
Code Project - .NET
http://www.codeproject.com/dotnet/cominterop.asp
#Exposing .NET Components to COM - The Code Project - .NET
http://www.codeproject.com/dotnet/nettocom.asp
#Exposing COM interfaces of a .NET class library for Late Binding - The
Code Project - VB.NET
http://www.codeproject.com/vb/net/MusaExposingCOM.asp
#Chapter 3: Recommendations for Managed and Unmanaged Code Interoperability
http://msdn2.microsoft.com/en-us/library/ms993883.aspx
Hope this helps.
Regards,
Walter Wang (wawang@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.
JerryWEC - 24 Jan 2007 16:08 GMT
Walter,
Thanks for all the information and help! I have been reading as much as I can about COM Interop!
I have figured out how to finally see the method, properties and events in the base class!!!...
I replaced the following ComClass() attribute with ClassInterface() attribute below and now my base class methods, properties and events can be seen by my VB6 project.
<ComClass(ComLogging.ClassId, ComLogging.InterfaceId, ComLogging.EventsId)> _
<ClassInterface(ClassInterfaceType.AutoDual)> _
However, my events now have add_ and remove_ prefixed to my event names and the Sub for the add_ and remove_ events are passing the arguments as follows:
Sub add_LogErrorOccurred(obj As LogErrorOccurredEventHandler)
Can you tell me what is going on with these add_ and remove_ methods?
Are there any issues with using ClassInterface() attribute in this manner? Is there a better way to wrap my Logging class public interface of methods, properties and events?
I'm still learning... TIA JerryM
JerryWEC - 24 Jan 2007 22:45 GMT
Hi Everyone,
ComClass() attribute is good for out of the box class wrapping but not if your inheriting from a base class...
"<ComClass(ComLogging.ClassId, ComLogging.InterfaceId, ComLogging.EventsId)> _
<ClassInterface(ClassInterfaceType.AutoDual)> _
ClassInterface(ClassInterfaceType.AutoDual) seems to have some issues with version upgrades of your com class (I read this).
According to what I read the best way to do COM Interop is to use ClassInterface(ClassInterfaceType.None) attribute and to use a public interface for your base class.
I'm sure there are other issues I'll have to work out like events, etc... But it looks like this attribute will expose my interface for my base class. Right now I have the interface in my file with my base class, but, I'm thinking I may have to move it to the ComClass wrapper file. I know there are some methods, properties and events that will have to be modified for the VB6 / Com client. I'll have to override these methods and change the code to play nice with VB6.
Any additional comments would be greatly appreciated.
I'll post another post for some questions on Com Interfaces / event issues.
JerryM
Walter Wang [MSFT] - 26 Jan 2007 06:33 GMT
Hi Jerry,
Yes the ClassInterfaceType.AutoDual is not recommended since it have some
issues with versioning support. Please refer to
http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.clas
sinterfacetype.aspx for more info.
I've posted some comments to your new post about the ComSourceInterfaces
attribute. Is it ok to let us keep the discussion there?
Regards,
Walter Wang (wawang@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.