【问题标题】:C# COM objects with VB6/asp error带有 VB6/asp 错误的 C# COM 对象
【发布时间】:2011-02-17 00:46:27
【问题描述】:

我正在尝试通过 COM 公开一个 C# 类库,以便我可以在经典的 asp 网站中使用它。

我使用过 sn - k、regasm 和 gacutil。我现在能做的就是回显字符串。

将类变量作为输入的方法对我不起作用。即我的返回名字和姓氏字符串的测试方法 EchoPerson(Person p) 不起作用。我收到运行时错误 5 - 无效的过程调用或参数。

请让我知道我缺少什么。我也没有 VB 的智能。我需要做什么才能让智能工作。

下面是我的 C# 测试代码

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);
        }

    }

}

和 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

【问题讨论】:

    标签: c# com asp-classic vb6


    【解决方案1】:

    这是您应该考虑使用的模式:-

    [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;
        }
    }
    

    这种方法让您可以更好地控制 .NET 组件公开的 COM 接口。只有接口定义的成员才会被 COM 客户端使用。

    【讨论】:

    • 是的,安东尼是对的。 Ken 的代码可以通过暴露 COM 接口来增强很多
    【解决方案2】:

    当您在 COM 接口中使用复杂类型时,您需要使用带有[StructLayout(LayoutKind.Sequential)] 属性的结构。您可以在 MSDN 上找到更多信息:Exported Type Conversion。由于 COM 必须跨边界编组类型,因此您必须确保您的所有类型都可以成功复制到非托管区域。引用类型不会成功。

    【讨论】:

      【解决方案3】:
       public string EchoPerson(ref Person p)
      

      您收到错误,因为您使用 ref 关键字声明了参数。这是不正确的,Person 已经是一个引用类型,而 VB6 使用的对象是一个变体,而不是 Person。只需省略“参考”。顺便说一句,在 VB6 中使用 Option Explicit On 是一种很好的做法。

      您没有获得 IntelliSense,因为您可能没有使用 [InterfaceType(ComInterfaceType.InerfaceIsDual)] 声明接口。 Microsoft 建议不要这样做,因为双接口的 DLL Hell 问题。虽然需要一个类型库来帮助 VB6 显示您想要的 IS。

      【讨论】:

      • VB6 中的“Option Strict On”?在 VB.NET 中是但不是 VB6 只是 Option Explicit
      猜你喜欢
      • 2010-10-11
      • 1970-01-01
      • 2012-08-21
      • 2011-05-07
      • 2011-09-09
      • 2017-05-05
      • 2011-06-12
      • 2016-07-02
      • 2011-10-09
      相关资源
      最近更新 更多