C# COM objects with VB6/asp error

雨燕双飞 提交于 2019-12-12 18:07:51

问题


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. What 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

回答1:


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.




回答2:


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.




回答3:


 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.



来源:https://stackoverflow.com/questions/2791996/c-sharp-com-objects-with-vb6-asp-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!