【问题标题】:help: Call C# winforms dll from VB6 project?help: 从 VB6 项目调用 C# winforms dll?
【发布时间】:2009-12-17 09:35:15
【问题描述】:

我有一个 VB6 项目(Windows 应用程序),我必须在 C#.net 中的现有 VB6 项目中重新开发一个模块。

我用 C#.net 开发的模块应该是一个 dll 并且应该包含一些 windows 窗体。我能够从我的 vb6 项目中成功调用 c# 控制台应用程序 dll,但是当我尝试从我的 VB6 项目中调用带有 winforms 的 C# 类库时遇到了问题。

这是我为我的概念证明所做的 - 这是我的 C#.net 类库项目中的一个类文件。

namespace TestDll
{
    public interface IClass1
    {
        void DisplayMessage();
    }


    public class Class1:IClass1
    {              
        void IClass1.DisplayMessage()
        { 
            MessageBox.Show ("Displyaing message");
        }

    }
}

我在同一个 nemspace 中有一个表单,我计划实例化 Class1 并在 C# winform 的 page_load 事件上使用它的对象。

在我的 VB6 项目中,我想显示我在 C#.net dll 中的表单。我用这段代码调用它 -

Private Declare Sub DislayMessage Lib "TestDll.dll" ()

Private Sub Command1_Click() //On button click event of the VB6 windows form
DislayMessage
End Sub

我收到一个错误 - “在 TestDll.dll 的 DisplayMessage 中找不到 DLL 入口点”

我不确定如何解决此错误。我什至怀疑这是不是应该从 VB6.0 windows 应用程序调用包含一些 winforms 的 C#.net dll 的方式。

我应该在我的 VB6 代码中实例化 Class1 吗?如何解决此错误? 我的方法正确吗?有没有更好的方法来做到这一点?

TIA。

【问题讨论】:

标签: c# windows dll vb6 interop


【解决方案1】:

你必须让你的类 COM-Visible。以下是我将如何更改您的代码:

namespace TestDll
{
    [Guid("FB8AB9B9-6986-4130-BD74-4439776D1A3D")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IClass1
    {
        [DispId(50)]
        void DisplayMessage();
    }


   [Guid("74201338-6927-421d-A095-3BE4FD1EF0B4")]
   [ClassInterface(ClassInterfaceType.None)]
   [ComVisible(true)]
   [ProgId("TestDll.Class1")]
    public class Class1:IClass1
    {              
        void IClass1.DisplayMessage()
        { 
            MessageBox.Show ("Displyaing message");
        }

    }
}

注意[DispId(50)]。您希望为 COM 可见的方法、属性和事件指定调度 ID。如果你不这样做,编译器会为你做这件事,你可能会在每次编译时破坏兼容性。这个数字并不重要,因为它在编译之间不会改变。

您可能想查看Building COM Objects in C#。这是一个很好的入门教程。

一些亮点:

将 VC# 对象暴露给 COM 世界需要以下……

* The class must be public
* Properties, methods, and events must be public.
* Properties and methods must be declared on the class interface.
* Events must be declared in the event interface.

每个接口都需要一个 GUID 属性 设置在接口名称之前。到 生成唯一的 Guid ,使用 guidgen.exe 实用程序并选择 注册表格式。

【讨论】:

  • 我们如何在测试项目中测试方法?由于我使用了这种方法,我面临着一个只有一个类的意外类型的 CoCreateInstance...
  • @menssana 我认为您应该就此而不是在 cmets 中提出问题。更有可能得到回应。
  • 你是对的,但由于这几周没有时间,我至少会给我 2 美分。我用我的所有代码创建了一个常规类,然后创建了一个带有 GUID 的专用类和所有必需的东西来实例化“常规类”。这样,我可以使用常规类在 .NET 中对其进行测试。必须说我有(无法解释为什么并判断是否真的有必要)注册两个程序集;一个带有 GUID 和一个“常规”的。
【解决方案2】:

这样做的唯一方法是将 C# 类公开为 COM 对象(也称为 CCW - COM 可调用包装器),并在 VB6 代码中创建该 COM 对象的实例。

这应该可以帮助您入门:

http://www.bing.com/search?q=C%23+CCW&go=&form=QBRE&qs=n

【讨论】:

  • 好吧,不是 only 方法,而是唯一 sane 方法:-P
  • 谢谢。这是非常有帮助的。但是,我还是很好奇。你能告诉我我上面发布的代码有什么问题吗?
  • C-Pound Guru 总结得很好。
【解决方案3】:

【讨论】:

    猜你喜欢
    • 2013-02-27
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 2013-11-26
    相关资源
    最近更新 更多