简体   繁体   English

如何通过后期绑定从VB.Net调用位于C#DLL中的方法

[英]How to call a method located inside a C# DLL, from VB.Net, with late binding

I can't get a grip on how the various "Init", "Accumulate" ... methods work, to enable calling a method located inside a DLL, from VB.Net code. 我无法掌握各种“ Init”,“ Accumulate” ...方法的工作方式,以便能够从VB.Net代码调用位于DLL中的方法。

Let's say the method to call has the following signature : 假设要调用的方法具有以下签名:

public double ComputeMeanPosition(ref SortedList<DateTime, double> posByTime)

Would you please kindly point me to an actual example of the use of the methods, or simply give me a few hints as how to actually pass the parameters to the method, call it and fetch the results ? 您能给我一个使用方法的实际例子,还是给我一些提示,如如何将参数实际传递给方法,调用它并获取结果?

@Olivier Jacot-Descombes: I definitely prefix the class name by the namespace name, but yet fail to be able to reach the object. @Olivier Jacot-Descombes:我肯定用名称空间名称作为类名称的前缀,但无法访问该对象。 In fact I am surprised that your kind suggestion does not involve the following methods, displayed through introspection of the loaded DLL : 实际上,令您惊讶的是,您的建议没有涉及通过装入的DLL的内省显示的以下方法:

Type: MyClassName
        Method: Void Init()
        Method: Void Accumulate(System.Data.SqlTypes.SqlDouble, System.Data.SqlTypes.SqlDateTime, System.Data.SqlTypes.SqlBoolean)
        Method: Void Merge(MyClassName)
        Method: System.Data.SqlTypes.SqlDouble Terminate()
        Method: Void Write(System.IO.BinaryWriter)
        Method: Void Read(System.IO.BinaryReader)
        Method: Boolean Equals(System.Object)
        Method: Int32 GetHashCode()
        Method: System.String ToString()
        Method: System.Type GetType()

EDIT 编辑

In fact I have a code similar to the following one, that successfully manages to inspect the DLL and gets several types and methods out of it, giving the following results above for the method I would like to call. 实际上,我有一个类似于以下代码的代码,该代码成功地检查了DLL并从中获取了几种类型和方法,从而为我要调用的方法提供了以下结果。

Here is the code 这是代码

  For Each oneModule As Reflection.Module In useAssembly.GetLoadedModules() Console.WriteLine(" - " & oneModule.Name) For Each oneType As System.Type In oneModule.GetTypes() Console.WriteLine(" Type: " & oneType.Name) For Each oneField As Reflection.FieldInfo In oneType.GetFields() Console.WriteLine(" Field: " & oneField.ToString()) Next oneField For Each oneMethod As Reflection.MethodInfo In oneType.GetMethods() Console.WriteLine(" Method: " & oneMethod.ToString()) [[ ADD "Invoke" here ?]] Next oneMethod Next oneType Next oneModule 

At the end, it seems that the [[...]] is at the place where the Invoke method should be called to call the method of my choice, but that is where I'm stuck... Would I need to build an object before calling it ? 最后,似乎[[...]]位于应调用Invoke方法以调用我选择的方法的地方,但这就是我遇到的问题……我需要构建调用对象之前? How should I pass it the parameters ? 我应该如何传递参数? How to get the result ? 如何获得结果?

Something like this should work: 这样的事情应该起作用:

using System;
using System.Reflection;
using System.IO;

public class MainClass
{
      public static int Main(string[] args)
      {
           Assembly a = null;
           try
           {
                a = Assembly.Load("YourLibraryName");
           }
           catch(FileNotFoundException e)
               {Console.WriteLine(e.Message);}

           Type classType = a.GetType("YourLibraryName.ClassName");

           object obj = Activator.CreateInstance(classType);

           object[] paramArray = new object[1];    
           paramArray[0] = new SortledList<DateTime, double>();
           MethodInfo mi = classType.GetMethod("ComputeMeanPosition");
           mi.Invoke(obj, paramArray);

           return 0;
       }
 }

For VB.NET: 对于VB.NET:

Imports System
Imports System.Reflection
Imports System.IO

Public Class MainClass
    Public Shared Function Main(args As String()) As Integer
        Dim a As Assembly = Nothing
        Try
            a = Assembly.Load("YourLibraryName")
        Catch e As FileNotFoundException
            Console.WriteLine(e.Message)
        End Try

        Dim classType As Type = a.[GetType]("YourLibraryName.ClassName")

        Dim obj As Object = Activator.CreateInstance(classType)

        Dim [paramArray] As Object() = New Object(0) {}
        [paramArray](0) = New SortledList(Of DateTime, Double)()
        Dim mi As MethodInfo = classType.GetMethod("ComputeMeanPosition")
        mi.Invoke(obj, [paramArray])

        Return 0
    End Function
End Class

Tested and this worked: 经过测试,此方法有效:

 Dim a As Assembly = Nothing
    Try
        a = Assembly.Load("TestLib")
    Catch ex As FileNotFoundException
        Console.WriteLine(ex.Message)
    End Try

    Dim classType As Type = a.[GetType]("TestLib.Class1")

    Dim obj As Object = Activator.CreateInstance(classType)

    Dim [paramArray] As Object() = New Object(0) {}
    [paramArray](0) = New SortedList(Of DateTime, Double)()
    Dim mi As MethodInfo = classType.GetMethod("ComputeMeanPosition")
    mi.Invoke(obj, [paramArray])

This is not the actual code, because I'm not in sitting in front of an actual c# editor, but something like this 这不是实际的代码,因为我不是坐在实际的C#编辑器前面,而是类似这样的东西

// using System.Reflection required

// first load the external assembly into the appdomain and 
// create an instance of the object
var assembly = Assembly.Load("Path to the Assembly");
var type = assembley.GetType("TheNameOfTheClass");
var ctor = type.GetConstuctor();
var object = ctor.Invoke(); // assuming an empty construtor, else you'll need to pass in data

// next invoke the method
var methodInfo = assembly.GetMethodByName("ComputeMeanPosition");
var param = new SortedList<DateTime, double>();
var result = methodInfo.Invoke(object, new object[] { param });

You can call this method as if was declared like this in VB 您可以像在VB中这样声明的方式调用此方法

Public Function ComputeMeanPosition( _
    ByRef posByTime As SortedList(Of DateTime, Double)) As Double

Note: I used this online snippet converter to convert the C# code to VB. 注意:我使用此在线代码片段转换器将C#代码转换为VB。 You have to add an empty method body {} to the C# method header before converting it. 在转换之前,必须在C#方法头中添加一个空的方法主体{}

public double ComputeMeanPosition(ref SortedList<DateTime, double> posByTime) {}

As this method is not declared as static in C# ( Shared in VB) you first need to create an object. 由于此方法在C#中未声明为static方法(在VB中为Shared ),因此您首先需要创建一个对象。 The method is most likely declared inside a class. 该方法很可能在类中声明。 Let's say the class was named "MyClass", then you would have to write something like this 假设该类被命名为“ MyClass”,那么您将不得不编写如下内容

Dim posByTime = New SortedList(Of DateTime, Double)()
Dim obj = New MyClass()
Dim result As Double = obj.ComputeMeanPosition(posByTime)

If the constructor (the New method) declares arguments, you will have to pass them when creating the object 如果构造函数( New方法)声明了参数,则在创建对象时必须传递参数

Dim obj = New MyClass(arg1, arg2, ...)

Depending on what ComputeMeanPosition expects, you will have to add items to the list posByTime before calling it. 根据ComputeMeanPosition期望,您必须在调用posByTime列表之前将其添加到列表中。


If the method was declared as static in C# ( Shared in VB), you would qualify it with the class name, instead of creating an object. 如果在C#中将方法声明为static方法(在VB中为Shared ),则可以使用类名对其进行限定,而不是创建一个对象。

Dim posByTime = New SortedList(Of DateTime, Double)()
Dim result As Double = MyClass.ComputeMeanPosition(posByTime)

UPDATE 更新

If you load the assembly dynamically you will probably do something like this 如果动态加载程序集,则可能会执行以下操作

Dim ass As Assembly = Assembly.LoadFrom("C:\SomePath\MyDll.dll")
Dim obj As Object = ass.CreateInstance("MyClass", True) 

Dim posByTime = New SortedList(Of DateTime, Double)()
Dim result As Double = obj.ComputeMeanPosition(posByTime)

And you will have to set the Option Strict Off for late binding. 并且您必须将Option Strict OffOption Strict Off设置为后期绑定。


If the constructor requires arguments, you will have to pass them to another overload of CreateInstance 如果构造函数需要参数,则必须将其传递给CreateInstance另一个重载

Dim args = new Object() { arg1, arg2, ... }
Dim obj As Object = ass.CreateInstance("MyClass", True, _
    BindingFlags.Public Or BindingFlags.Instance, Nothing, Nothing, _
    args, Nothing, Nothing)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM