Frage

Ich habe eine .net DLL in c # geschrieben, die Daten aus einer Datenquelle liest und fungiert als ein Wrapper andere Anwendungen zu ermöglichen, seine Funktion aufzurufen, diese Daten abzurufen. die Sache ist, ich die .net dll nicht gerechnet haben, als .net apps für andere verwendet werden, ich so jetzt gesagt wurde, das alles in einem vba / Powerpoint-Makro verwendet werden soll, die ich meine, ist ziemlich ähnlich wie ein VB6 app , so dass ist, wie ich es testen jetzt habe vor.

Nach einigen googeln und sogar in so einige Fragen hier zu veröffentlichen, ich verwalten die DLL erhalten innerhalb von VB6 referenziert werden, aber wenn ich versuche, eine Funktion aufzurufen, die alle Parameter haben, ich werde den Fehler Laufzeit erhalten Meldung des Fehlers 450 falsche Anzahl von Argumenten oder ungültiger Eigenschaftszuweisung.

Fragen

Also, was mache ich falsch? und kann jemand bitte einige Ressourcen oder Beispielcodes liefern, die ich lernen kann, wie man richtig eine .net dll schreiben, die Funktionen mit Parametern, die von VB6 / VBA-App aufgerufen werden können?

Und wenn meine Codes ein bisschen zu chaotisch lesen :), dann vielleicht Jungs können Sie mir helfen, zu sagen, wie Parameter setzen in Arbeit diese Probe, die ich von Codeproject lernen, seine die gleiche Fehlermeldung zurückkehrt, wenn ich dort einige Parameter enthalten.

UPDATES:

fand ich einen anderen Satz von Beispielcodes hier , aber leider es geht nur Parameter als ganze Zahl, und wenn ich versuche, eine Beispielfunktion zu tun, die Parameter als Zeichenfolge übergibt, i die gleichen Fehler. Fehle ich etwas Grundlagen hier? jemand kümmert eine noobie entflammen?

Updates 2:

Für den Fall, gibt es jemand anderes, der auf dieses Problem gestoßen, habe ich nicht wirklich herausgefunden, warum oder was das Problem verursacht, aber da das Projekt noch ziemlich klein war, habe ich nur eine Arbeitsprobe für die DLL verwenden die in der Lage war, zurückzukehren Zeichenfolge richtig und Start-Funktion pro Funktion über, um es zu bewegen, und es funktioniert gut jetzt:)

Dank !!!

die .net dll-Codes sind wie folgt:

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)
        {
        ...
        }
}

und das ist, wie ich es von VB6 bin Aufruf:

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
War es hilfreich?

Lösung

ich bemerkt, dass Sie [ComVisible(true)] sind vermisst.

Schnittstelle Header aussehen sollte:

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

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

Klasse Header aussehen sollte:

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

Andere Tipps

Versuchen Sie dieses Stück Code zu ändern: -

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

Ich bin mir nicht sicher, warum Sie die Fehlermeldung erhalten Sie jedoch früh (oder VTable) verbindlich ist, was Sie VB6-Code zu sein scheint versucht, aber InterfaceIsIDispatch unterstützt das nicht. Es ist möglich, VB6 selbst fällt zurück auf die späte Bindung, aber warum wollen Sie es?

Auch fallen alle DispID Attribute sie sind nur nötig, wenn Sie wirklich eine vorhandene COM-Schnittstelle müssen emulieren.

Ich glaube, DispID (1) für ToString oder so ähnlich reserviert ist (es ist schon eine Weile) Versuchen Sie beginnen Ihre DispIDs bei 2.

Haben Sie versucht, bei der Typbibliothek suchen (mit Oleview.exe), nachdem Sie exportierten / registriert die Montage?

Mein Verdacht ist, dass alle Ihre Methoden Strings zurückgeben, während COM-Methoden neigen HRESULT des zurückzukehren (keine Ahnung, ob dies in der Regel wahr ist - eigentlich Ihr Beispiel Codeproject Seite scheint anders vorzuschlagen), was bedeutet, Sie müssen Ihre Eingabe setzen würde und Ausgabe in die Methodenargumente und explizit Marschall mit [in], [out] und / oder [retval].

Wie auch immer, werfen Sie einen Blick auf die Art Bibliothek und prüfen, ob es sieht aus wie Sie es erwarten aussehen. Wenn nicht können Sie explizit müssen Ihre Typen Marschall das MarshalAs Attribut verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top