I'm trying to expose a C# class library via COM so that I can use it in a classic asp web site.
I've used sn - k, regasm and gacutil. About all I can do now though is echo back strings.
Methods which take Class variables as input are not working for me. ie my test method EchoPerson(Person p) which returns a string of the first and last name doesn't work. I get a runtime error 5 - Invalid procedure call or argument.
Please let me know what I am missing. Also I have no intellisence in VB. Wha开发者_开发技巧t do I need to do to get the intellisence working.
Below is my C# test code
namespace MrdcToFastCom
{
public class Person : MrdcToFastCom.IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class ComTester : MrdcToFastCom.IComTester
{
public string EchoString(string s)
{
return ("Echo: " + s);
}
public string Hello()
{
return "Hello";
}
public string EchoPerson(ref Person p)
{
return string.Format("{0} {1}", p.FirstName, p.LastName);
}
}
}
and VB6 call
Private Sub btnClickMe_Click()
Dim ct
Set ct = New MrdcToFastCom.ComTester
Dim p
Set p = New MrdcToFastCom.Person
p.FirstName = "Joe"
p.LastName = "Test"
Dim s
s = ct.EchoPerson(p) ''#Error on this line
tbx1.Text = s
End Sub
Here is the pattern you should consider using:-
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("B4CAC74B-ADE0-4ac7-AD0E-26E6439F9CF7")]
public interface _IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("A3C553DC-A348-43e4-957A-F94D23E3300E")]
public class Person : _IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("4B527235-6738-4853-BEA0-FB3087C89291")]
public interface _ComTester
{
string EchoPerson(Person person);
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("C753D72B-C802-44ae-946A-E3F6D7C5D14B")]
public class ComTester : _ComTester
{
public string EchoPerson(Person person)
{
return person.FirstName + " " + person.LastName;
}
}
This approach gives you much more control over the COM Interface exposed by the .NET components. Only the members defined by interface are exposed for consumption by COM clients.
When you are using complex types in COM interfaces, you need to use structs that are attributed with [StructLayout(LayoutKind.Sequential)]
. You can find more information here on MSDN: Exported Type Conversion. Since COM has to marshal the types across the boundary, you have to make sure all your types can be copied across into unmanaged land successfully. Reference types won't make it.
public string EchoPerson(ref Person p)
You are getting an error because you declared the argument with the ref keyword. That's not correct, Person is already a reference type and the object that VB6 is using is a variant, not a Person. Just omit "ref". Using Option Explicit On is a good practice in VB6 btw.
You are not getting IntelliSense because you probably didn't declare the interfaces with the [InterfaceType(ComInterfaceType.InerfaceIsDual)]. Microsoft recommends against this because of the DLL Hell problems with dual interfaces. Required though to get a type library to help VB6 display the IS you want.
精彩评论