Question

J'ai un dll .net écrit en C # qui lit les données hors d'une source de données et agit comme un wrapper pour permettre à d'autres applications d'appeler sa fonction pour récupérer ces données. la chose est que je ne l'ai pas anticiper les dll .net à utiliser pour d'autres que les applications .net, maintenant on m'a dit que tout cela va être utilisé dans une macro vba / powerpoint que je figure est assez similaire à une application VB6 , de sorte que comment je prévois de le tester en ce moment.

après quelques recherches sur Google et l'affichage même une question ici donc, je parviens à obtenir le dll être référencé à l'intérieur de VB6, mais lorsque je tente d'appeler une fonction qui ont des paramètres, je vais l'erreur d'exécution un message d'erreur 450 nombre incorrect d'arguments ou assignation de propriété non valide.

Questions

Alors qu'est-ce que je fais mal? et quelqu'un peut-il s'il vous plaît fournir des ressources ou des exemples de code que je peux apprendre sur la façon d'écrire correctement une dll .net qui a des fonctions avec des paramètres qui peuvent être appelés à partir de l'application VB6 / vba?

Et si mes codes sont un peu trop désordonné pour lire :), alors vous avez peut-être aider à me dire comment mettre les paramètres à travailler dans cet échantillon que j'apprendre de CodeProject , son retour le même message d'erreur quand j'inclus certains paramètres là.

MISES À JOUR:

je l'ai trouvé un autre ensemble de codes d'échantillons ici , mais malheureusement il ne passe que des paramètres comme entier, et lorsque je tente de faire une fonction d'échantillon qui transmet les paramètres sous forme de chaîne, je reçois la même erreur. Suis-je manque quelque chose ici les fondamentaux? Quelqu'un veut une flamme noobie?

Mises à jour 2:

Juste au cas où il y a quelqu'un d'autre qui a trébuché sur ce problème, je ne l'ai pas vraiment trouvé pourquoi ou ce qui était à l'origine du problème, mais depuis que le projet était encore assez faible, je viens d'utiliser un échantillon de travail pour la dll qui a pu pour revenir chaîne correctement et lancer la fonction par fonction déplacement sur lui, et il fonctionne très bien maintenant:)

merci !!!

les codes dll .net sont les suivants:

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

et voilà comment je suis l'appeler de 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
Était-ce utile?

La solution

J'ai remarqué que vous manquez [ComVisible(true)].

En-tête de l'interface devrait ressembler à:

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

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

En-tête de classe devrait ressembler à:

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

Autres conseils

Essayez de changer ce morceau de code: -

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

à

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

Je ne sais pas pourquoi vous obtenez l'erreur que vous êtes cependant tôt (ou VTable) de liaison est ce que vous le code VB6 semble tenter, mais InterfaceIsIDispatch ne supporte pas. Il est possible VB6 lui-même est en train de revenir à la liaison tardive, mais pourquoi voudriez-vous à?

drop également tous les attributs DispId ils ne sont nécessaires que si vous avez vraiment besoin d'émuler une interface COM existant.

Je crois DispID (1) est réservé pour ToString ou quelque chose comme ça (il a été un certain temps) Essayez de démarrer votre dispids à 2.

Avez-vous essayé de regarder la bibliothèque de type (en utilisant Oleview.exe) après avoir exporté / enregistré l'assemblée?

Je soupçonne que toutes vos méthodes renvoient des chaînes, alors que les méthodes COM ont tendance à revenir de HRESULT (aucune idée si cela est généralement vrai - en fait votre exemple page CodeProject semble suggérer le contraire), ce qui signifie que vous devrez mettre vos commentaires et sortie dans les arguments de la méthode et les maréchal explicitement [en], [out], et / ou [retval].

Quoi qu'il en soit, jetez un oeil à la bibliothèque de type et vérifier s'il semble que vous attendez à regarder. Sinon, vous devrez peut-être maréchal explicitement vos types en utilisant l'attribut MarshalAs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top