我已经写在c#读取数据从一个数据源,并作为一个包装,以允许其他应用程序来调用其功能来检索这些数据的NET的DLL。事情是我没有预料到.NET的DLL用于.NET相比其他的应用程序,所以现在有人告诉我这一切是怎么回事在VBA / PowerPoint的宏,我的身影使用是相当类似VB6应用程序,所以这是如何我打算现在对其进行测试。

后,一些谷歌上搜索,甚至在所以在这里张贴了一些问题,我设法得到的dll VB6内被引用,但是当我尝试调用它有任何参数的函数,我会得到错误运行时的错误450错误的参数数目或无效的属性分配消息。

问题

那我做错了什么?并且有人可以请提供一些资源或示例代码,我可以了解如何正确地写,其具有的功能与可以从VB6 / VBA应用被调用的参数的NET的DLL?

如果我的代码是有点太乱阅读:),那么也许你们可以帮告诉我如何把参数工作中的该样品,我从CodeProject 时,其返回相同的错误消息时,我包括一些参数那里。学会

更新

我发现另一组示范码此处,但不幸它只是传递参数为整数,当我尝试做这传递参数字符串样本函数,我得到了同样的错误。我思念的东西在这里基本面?有人关心火焰一个noobie?

更新2:

万一有其他人谁无意中发现了这个问题,我并没有真正找到了原因或者是什么原因导致的问题,但由于该项目仍相当小,我只是用一个工作样本这是能够的dll正确返回字符串,并开始移动每个功能的函数到它,它现在工作正常:)

感谢!!!

的NET的DLL代码如下:

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-0542A0FC7040")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface _Program
    {
        [DispId(1)]
        string Get_All_Locales(string test);

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

        [DispId(8)]
        void Constructor(string directory);

    }

    [Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA5")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("DtasApiTool.Program")]
    public class Program : _Program
    {
        private string connStr = "";
        private string xmlLocation = "";

        public Program(){

        }

        public void Constructor(string directory)
        {
          ...  
        }


        #region This part contains all the internal functions

        /// <summary>
        /// return the component lesson given a locale and skill id
        /// </summary>
        /// <param name="locale"></param>
        /// <param name="skillId"></param>
        /// <returns></returns>
        internal string Get_Component_Lesson(string locale, string skillId)
        {
            ...
        }

        /// <summary>
        /// return a xmlFile containing all the information from the Skill Analysis
        /// </summary>
        /// <param name="fileLocation">raw xml file location, i.e. C://datapath/raw_dato.xml</param>
        /// <returns> the location of the output xml file.</returns>
        internal string Process_Skill_Analysis_Report(string fileLocation)
        {            
...
}

        #endregion

        /// <summary>
        /// Returns all the locale which is in the database currently.
        /// </summary>
        /// <returns></returns>
        public string Get_All_Locales(string test)
        {
        ...
        }
}

和这是如何即时从VB6调用它:

Option Explicit

Private Sub Form_Load()        
    Dim obj As DtasApiTool.Program
    Set obj = New DtasApiTool.Program

    Dim directory As String
    directory = """" + "C:\Documents and Settings\melaos\My Documents\Visual Studio 2008\Projects\app\bin\Release\" + """"

    'obj.Constructor directory
    Dim func As String
   func = obj.Get_All_Locales(directory)

End Sub
有帮助吗?

解决方案

我注意到你错过[ComVisible(true)]

接口头应该是这样的:

[Guid("CF4CDE18-8EBD-4e6a-94B4-6D5BC0D7F5DE")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface IFoo {

    [DispId(1)]
    string MyMethod(string value);
}

类的头应该是这样的:

[Guid("7EBD9126-334C-4893-B832-706E7F92B525")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
[ProgId("MyNamespace.Foo")]
public class Foo: IFoo {

    public string MyMethod(string value){
        return somestring;
    }
}

其他提示

尝试改变的代码这个块: -

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

我不知道为什么你得到你不过是早期(或虚函数表)的错误结合是出现什么你VB6代码进行尝试,但InterfaceIsIDispatch不支持。它可能VB6本身回落到后期绑定,但你为什么会想?

同时删除所有DISPID属性,如果你真的需要模仿现有的COM接口,他们才需要它。

相信DISPID(1)被预留给的ToString或类似的东西(它已经有一段时间) 尝试2开始你的DISPID。

您是否尝试寻找类型库(使用OLEView.exe这类)导出后/注册组件?

我怀疑的是,所有的方法返回字符串,而COM方法往往返回HRESULT的(不知道如果这是大致如此 - 其实你的例子在CodeProject页面似乎并非如此),这意味着你将需要把你的输入和输出到所述方法的参数,并明确与编组他们[IN],[OUT]和/或[RETVAL。

不管怎么说,看看类型库,并检查它看起来像你期望它看起来。如果没有,你可能必须明确地使用名帅MarshalAs特性的类型。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top