Problems creating COM wrapper for C# dll (regasm.exe)

  • Thread starter Thread starter tom
  • Start date Start date
T

tom

I called regasm.exe /tlb CameraManagement.dll and I got
CameraManagement.tlb

When I look inside with OleView.exe or create C++ header I see
something like that:


struct __declspec(uuid("37944845-f74f-3999-b972-d42355a78bcd"))
_AlarmSetting : IDispatch
{};

struct __declspec(uuid("5e6abb0e-b170-377d-9902-20bb5388a53c"))
_AlarmSetting2 : IDispatch
{};

struct __declspec(uuid("8969367c-f590-333c-994e-c0b2a37ce928"))
_Camera : IDispatch
{};

they're just empty interfaces, only enums are exported correctly - but
oryginal C# classes have plenty of methods ! Where have they gone ? Am
I missing something ?

Thanks in advance
Kamil
 
tom said:
they're just empty interfaces, only enums are exported correctly - but
oryginal C# classes have plenty of methods ! Where have they gone ? Am
I missing something ?

Verify that you don't have a [assembly: ComVisible(false)] attribute in the
assemblyinfo.cs. I believe that Visual Studio 2005 adds it by default.
 
Kamil,

Well, if you don't specify that you want a particular interface, then by
default, you will only be able to access your classes through late binding.

Besides making sure that ComVisible is set on the classes/assembly, what
you want to do is first create ^interfaces^ that you want to expose to COM.
This is important, because COM is interface-based, and quite frankly, you
should play nicely. So initially, you would do this:

[Guid("some guid")]
public interface IMyInterface
{
void DoSomething();
}

"some guid" is a guid of your own creation. You set the Guid attribute
so that you control the IID of the interface. Then, you create your
implementation, like so:

[ProgId("ProjectName.ClassName")]
[Guid("some guid")]
[ClassInterface(ClassInterfaceType.None)]
public MyClass : IMyInterface
{
public void DoSomething()
{
// Implementation here.
}
}

Now, in this, the ProgId attribute is the program id that your component
can be identified by. The Guid attribute is going to be the class id for
the component, and the ClassInterface attribute says that any functionality
exposed through COM is going to be through the interfaces that you specify,
and not through the class definition.

So, when you export this now and register it, you should be able to see
the interface types in OLEVIEW, as well as the coclass definitions. You
would use the CLSID (the value in the Guid attribute on the MyClass
definition) to pass to CoCreateInstance and ask for the IID (the value for
the Guid attribute you defined on the IMyInterface interface) and then use
that.

Hope this helps.
 
Thank you for the answer Nicholas. Unfortunately, despite I posted this
question on C# group, I have no source code for this library, so I can't add
any interfaces to it. It seems that IDispatch is the only option for me :(

Kamil


U¿ytkownik "Nicholas Paldino [.NET/C# MVP]"
Kamil,

Well, if you don't specify that you want a particular interface, then
by default, you will only be able to access your classes through late
binding.

Besides making sure that ComVisible is set on the classes/assembly,
what you want to do is first create ^interfaces^ that you want to expose
to COM. This is important, because COM is interface-based, and quite
frankly, you should play nicely. So initially, you would do this:

[Guid("some guid")]
public interface IMyInterface
{
void DoSomething();
}

"some guid" is a guid of your own creation. You set the Guid attribute
so that you control the IID of the interface. Then, you create your
implementation, like so:

[ProgId("ProjectName.ClassName")]
[Guid("some guid")]
[ClassInterface(ClassInterfaceType.None)]
public MyClass : IMyInterface
{
public void DoSomething()
{
// Implementation here.
}
}

Now, in this, the ProgId attribute is the program id that your
component can be identified by. The Guid attribute is going to be the
class id for the component, and the ClassInterface attribute says that any
functionality exposed through COM is going to be through the interfaces
that you specify, and not through the class definition.

So, when you export this now and register it, you should be able to see
the interface types in OLEVIEW, as well as the coclass definitions. You
would use the CLSID (the value in the Guid attribute on the MyClass
definition) to pass to CoCreateInstance and ask for the IID (the value for
the Guid attribute you defined on the IMyInterface interface) and then use
that.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


tom said:
I called regasm.exe /tlb CameraManagement.dll and I got
CameraManagement.tlb

When I look inside with OleView.exe or create C++ header I see
something like that:


struct __declspec(uuid("37944845-f74f-3999-b972-d42355a78bcd"))
_AlarmSetting : IDispatch
{};

struct __declspec(uuid("5e6abb0e-b170-377d-9902-20bb5388a53c"))
_AlarmSetting2 : IDispatch
{};

struct __declspec(uuid("8969367c-f590-333c-994e-c0b2a37ce928"))
_Camera : IDispatch
{};

they're just empty interfaces, only enums are exported correctly - but
oryginal C# classes have plenty of methods ! Where have they gone ? Am
I missing something ?

Thanks in advance
Kamil
 
kamil said:
Thank you for the answer Nicholas. Unfortunately, despite I posted this
question on C# group, I have no source code for this library, so I can't
add any interfaces to it. It seems that IDispatch is the only option for
me :(

Kamil

Not necessarily, it's possible that the library implementer has
deliberately not set "Comvisible" because it wasn't designed to be used from
native COM clients, especially not from late bound clients.


Willy.
 
Back
Top