C # COM objects with VB6 / asp error

I am trying to open a C # class library via COM so that I can use it on a classic asp website.

I have used sn-k, regasm and gacutil. All I can do now, though, is echo backwards lines.

Methods taking class variables as input don't work for me. those. my EchoPerson (Person p) validation method which returns the first and last name string does not work. I am getting runtime error 5 - Invalid procedure call or argument.

Please let me know what I am missing. Also, I have no intelligence in VB. What do I need to do to get intellisence to work.

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 calling VB6

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

      

+2


a source to share


3 answers


Here is the template you should be 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 .NET components. Only the principals defined by the interface are exposed for COM clients.

+2


a source


When you use complex types in COM interfaces, you need to use structures that are specific to [StructLayout(LayoutKind.Sequential)]

. You can find more details here on MSDN: Exported Type Conversion . Since COM has to march types across the boundary, you have to make sure that all of your types can be copied to unmanaged land successfully. Link types won't do this.



+1


a source


 public string EchoPerson(ref Person p)

      

You are getting an error because you declared an argument with the ref keyword. This is not correct, Person is already a reference type and the object that VB6 uses is a variant, not Person. Just omit "ref". Using Option Explicit On is good practice in VB6.

You don't get IntelliSense because you probably didn't declare interfaces with interface [InterfaceType (ComInterfaceType.InerfaceIsDual)]. Microsoft recommends against this due to problems with DLL Hell with two interfaces. It needs at least getting a type library to help VB6 map the required IS.

+1


a source







All Articles