【问题标题】:How to get my .net dll to be referenced in vba/com?如何让我的 .net dll 在 vba/com 中被引用?
【发布时间】:2009-08-13 07:33:09
【问题描述】:

我有一个用 c sharp 编写的 .net dll,它使用 linq 读取数据并将其返回给另一个调用 vba 应用程序。我没有为此计划,所以最初的项目是为了让另一个 .net 应用程序可以访问它而编写的。所以现在我才发现有很多关于 .net com 互操作性的东西。

所以我了解到我需要用户界面才能使其工作,并且我需要重新加载 dll 以创建一个类型库文件,我可以直接从 vba/vb6 应用程序引用该文件。

到目前为止,我遇到的问题是,当我执行此 Dim obj As DtasApiTool.Program 时,这很好,但在下一行设置 obj = new DtasApiTool.Program 将导致新运算符未正确使用的错误。当我测试another .net dll from codeproject 时,它工作正常。

所以我的问题是,我在这里做错了什么?

  1. 我是否使用了太多引用,例如 使用system.xxx?
  2. 还是到期了 到我在 项目,即 app.config 文件等。
  3. 我如何获得 guid?

由于我在所有这方面的知识或经验非常有限,我根据代码项目中的示例代码是对是错的:(所以请随意评论任何事情。

这是我正在使用的代码:

using System;
using System.Collections.Generic;

using System.Linq;
using System.Text;
using System.Configuration;
using System.Data.OleDb;
using System.Data;
using System.Xml;
using System.Xml.Linq;
using System.IO;
//using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
//using System.Windows.Forms;

namespace DtasApiTool
{
    [Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7059")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface _Program
    {
    [DispId(1)]
    string Get_All_Locales();

    [DispId(2)]
    string Get_All_Levels(string locale);

    [DispId(3)]
    string Get_Subjects_ByLocaleLevelId(string locale, int levelId);

    [DispId(4)]
    string Get_Topic_ByLevelIdLocaleSubjectId(int levelId, string locale, int subjectId);

    [DispId(5)]
    string Get_Subtopic_ByLevelIdLocaleSubjectIdTopicId(int levelId, string locale, int subjectId, int topicId);

    [DispId(6)]
    string Get_Skill_ByLevelIdLocaleSubjectIdTopicIdSubtopicId(int levelId, string locale, int subjectId, int topicId, int subtopicId);

    [DispId(7)]
    string Get_All_Subjects(string locale);

}

[Guid("09FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("DtasApiTool.Program")]
public class Program : _Program
{
...}
}

【问题讨论】:

  • 您是否检查了项目属性中的“注册 COM 互操作”标志?
  • 是的,这是我做的第一件事

标签: c# .net com interop


【解决方案1】:

嗯 - 我一直在使用 C# DLL 和 COM,从来没有遇到过问题。我什至没有使用您那里的界面方法。例如,这是我通过 COM 在 Microsoft Dynamics NAV 中使用的 DLL 的匿名部分:

using ...;

namespace SomeCOMTool
{
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("MyCOMTool")]
    [ComVisible(true)]
    [Guid("your-guid-here without curly brackets!")]
    public class MyCOMTool
    {
        /// <summary>
        /// Empty constructor used by Navision to create a new instance of the control.
        /// </summary>
        public MyCOMTool()
        {
        }

        [DispId(101)]
        public bool DoSomething(string input, ref string output)
        {
        }
    }
}

当然,“COM 可见”是在程序集选项中设置的,并且在相应的字段中还有一个 GUID。

【讨论】:

  • @Thorsten,我已经将我的问题缩小到我使用的构造函数有一个似乎导致问题的参数值。所以我不允许在这种情况下使用任何带参数的构造函数吗?
  • 当使用带有 Navision 的 COM 时,构造函数必须是无参数的,但我不能告诉你这是否总是一个要求 - 因为我对 COM 互操作了解不够。如果有疑问,请删除参数并提供一个 Init 方法,该方法接受参数并执行您在构造函数中完成的初始化。
  • 另外,在你的描述“set obj = ...”中你没有写任何关于参数的东西——也许这就是问题所在?不带参数调用构造函数?
  • @Thorsten,我的函数中包含参数似乎有问题。当我尝试通过 function_name(parameter) 在 vb6 中调用它们时,我得到一个错误运行时错误 450 错误数量的参数或无效的属性分配。
  • 我不是 VB6 专家,但在模块开头添加“Option Explicit”可能有助于确保所有变量都被实际声明。否则,我建议您打开一个新问题并明确询问您的 450 错误。
猜你喜欢
  • 1970-01-01
  • 2018-09-13
  • 2017-09-29
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
相关资源
最近更新 更多