Pregunta

tengo un DLL .NET escrito en C #, que lee los datos de una fuente de datos y actúa como un contenedor para permitir que otras aplicaciones para llamar a su función para recuperar esos datos. la cosa es que no anticipé la dll .net para ser utilizado para otra cosa que aplicaciones .NET, por lo que ahora me dijeron que todo esto va a ser utilizado en una macro VBA / PowerPoint, que me imagino es bastante similar a una aplicación de VB6 , de modo que es como tengo la intención de probarlo en este momento.

después de algunas google e incluso publicar alguna cuestión aquí en esto, me las arreglo para obtener la DLL que se hace referencia en el interior de VB6, pero cuando trato de llamar a una función que tiene parámetros, voy a conseguir el error en tiempo de ejecución mensaje de error 450 número incorrecto de argumentos o asignación de propiedad no válido.

Preguntas

Entonces, ¿qué estoy haciendo mal? y por favor alguien puede proporcionar algunos recursos o códigos de ejemplo que puedo aprender sobre cómo escribir correctamente una DLL .NET que tiene funciones con parámetros que pueden ser llamadas desde la aplicación VB6 / VBA?

Y si mis códigos son un poco demasiado complicado para leer :), entonces tal vez ustedes pueden ayudar a decirme cómo poner parámetros para trabajar en esta muestra, que aprendo de CodeProject , la devolución del mismo mensaje de error cuando me incluyo algunos parámetros allí.

Actualizaciones:

me encontré con otro conjunto de códigos de muestra aquí , pero lamentablemente sólo pasa parámetros como número entero, y cuando intento hacer una función de ejemplo que pasa parámetros como cadena, me sale el mismo error. Me estoy perdiendo algo fundamentos aquí? a nadie le importa a la llama de un noobie?

Actualizaciones de 2:

Sólo en caso de que haya cualquier otra persona que se topó con este problema, realmente no me di cuenta de por qué o qué estaba causando el problema, pero ya que el proyecto todavía era bastante pequeña, sólo tiene que utilizar una muestra de trabajo para la DLL que fue capaz para volver cadena correctamente y comenzar la función por función en movimiento hacia él, y está funcionando bien ahora:)

gracias !!!

los códigos .NET DLL son los siguientes:

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

y así es como lo estoy llamando desde 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
¿Fue útil?

Solución

Me di cuenta de que se está perdiendo [ComVisible(true)].

cabecera interfaz debe ser similar a:

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

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

cabecera de la clase debe ser similar a:

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

Otros consejos

Trate de cambiar este trozo de código: -

[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]

a

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

No estoy seguro de por qué se obtiene el error sin embargo estás temprano (o Vtable) la unión es lo que parece que el código de VB6 estar intentando pero InterfaceIsIDispatch no soporta eso. Su posible VB6 en sí está cayendo de nuevo a finales de unión, pero ¿por qué quieres que?

También se retiren todos los atributos de DispId sólo son necesarios si realmente se necesita para emular una interfaz COM existente.

Creo dispid (1) se reserva para ToString o algo por el estilo (que ha pasado un tiempo) Trate de comenzar sus DISPID a las 2.

¿Usted ha intentado buscar en la biblioteca de tipos (usando Oleview.exe) después de que ha exportado / registrado la asamblea?

Mi sospecha es que todos sus métodos devuelven cadenas, mientras que los métodos COM tienden a volver de HRESULT (ni idea de si esto es cierto en general - en realidad su página de ejemplo CodeProject parece sugerir lo contrario), lo que significa que tendría que poner su entrada y de salida en los argumentos del método y explícitamente ellos mariscal con [en], [out], y / o [retval].

En cualquier caso, echar un vistazo a la biblioteca de tipos y comprobar si se ve como usted espera que se vea. Si no es posible que tenga que reunir de manera explícita sus tipos utilizando el atributo MarshalAs.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top