Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / January 2007

Tip: Looking for answers? Try searching our database.

COM Wrapper ?s

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
JerryWEC - 23 Jan 2007 17:16 GMT
Hi All,

I'm getting the following message in VB2005...

"Warning 2 'Microsoft.VisualBasic.ComClassAttribute' is specified for class
'ComLogging' but 'ComLogging' has no public members that can be exposed to
COM; therefore, no COM interfaces are generated.
I:\DEV\CLA_Logging\CLA_Logging\ComLogging.vb 2 14 CLA_Logging"

Here is my COM Wrapper class...

<ComClass(ComLogging.ClassId, ComLogging.InterfaceId, ComLogging.EventsId)>
_

Public Class ComLogging

Inherits Logging

#Region "COM GUIDs"

' These GUIDs provide the COM identity for this class

' and its COM interfaces. If you change them, existing

' clients will no longer be able to access the class.

Public Const ClassId As String = "5fcb73e1-d493-41e4-804a-55404d09e520"

Public Const InterfaceId As String = "7296e948-b435-46ea-87a2-a8bdeea6f61d"

Public Const EventsId As String = "e688c517-e096-46f0-9be4-3489f71f172c"

#End Region

' A creatable COM class must have a Public Sub New()

' with no parameters, otherwise, the class will not be

' registered in the COM registry and cannot be created

' via CreateObject.

Public Sub New()

MyBase.New()

End Sub

End Class

What do I need to do to expose the public interface from inherited Logging
class?

TIA! JerryM
JerryWEC - 23 Jan 2007 21:59 GMT
Hi everyone,

I have more info... I've been able to add a public function to my com
wrapper class (created using VS2005 new item | com class) and this new
function gets rid of my warning!

However, what I really want to do is to expose my public methods and
properties and events that are in my base class (Logging).  Is this possible
and how do you do it? I have been reading on all of the com attributes and
it seems like it should do this automatically.

What gives? JerryM
Walter Wang [MSFT] - 24 Jan 2007 07:14 GMT
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.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.