简体   繁体   English

如何在c#中使用动态链接的dll

[英]How to use dynamically linked dll in c#

I imported the taglib-sharp dll (that had been copied to the bin/debug folder of my project) in my C# application and then used types and methods from the library in the following way:我在我的 C# 应用程序中导入了taglib-sharp dll (已复制到我项目的 bin/debug 文件夹),然后通过以下方式使用库中的类型和方法:

using TagLib;

private void method()
{
    TagLib.File file = TagLib.File.Create("C:\\temp\\some.mp3");
    TagLib.Tag tag = file.GetTag(TagLib.TagTypes.Id3v2);
}

Now I want to link the dll dynamically.现在我想动态链接 dll。 How can I implement the same functional in this case?在这种情况下如何实现相同的功能?

That, what I've tried:那,我试过的:

using System.Reflection

private void method()
{
    Assembly TagLib = Assembly.Load("taglib-sharp");
        
    Type TagLibFile = TagLib.GetType("File");
    dynamic LibFile = Activator.CreateInstance(TagLibFile);
    
    TagLibFile file = LibFile.Create("c:\\temp\\some.mp3");
}

In this implementation, VisualStudio says that I can't use the tagLibFile variable as a type.在这个实现中,VisualStudio 说我不能使用 tagLibFile 变量作为类型。 I supposed that when I get a type from dll, I will be able to create variables of this type.我认为当我从 dll 获取类型时,我将能够创建这种类型的变量。

By the way, is this approach is correct?顺便问一下,这种方法是否正确?

PS Also, I tried to use the invoke method, but I was not sure what object I should pass as a first argument. PS 另外,我尝试使用invoke方法,但我不确定应该将哪个对象作为第一个参数传递。

UPD UPD

Based on @nawfal's awnser below, I've got the following working code:基于下面@nawfal 的 awnser,我得到了以下工作代码:

using System.Reflection

private void method()
{
    Assembly TagLib = Assembly.Load("taglib-sharp");

    // get the File type
    var fileType = TagLib.GetType("TagLib.File");
    // get the overloaded File.Create method
    var createMethod = fileType.GetMethod("Create", new[] { typeof(string) });

    // get the TagTypes method that contains Id3v2 field
    Type tagTypes = TagLib.GetType("TagLib.TagTypes");
    // get the overloaded File.GetTag method
    var getTagMethod = fileType.GetMethod("GetTag", new[] {tagTypes});
    // obtain the file
    dynamic file = createMethod.Invoke(null, new[] { "C:\\temp\\some.mp3" });
    // obtain the Id3v2 field value
    FieldInfo Id3TagField = tagTypes.GetField("Id3v2");
    var Id3Tag = Id3TagField.GetValue(tagTypes);

    // obtain the actual tag of the file
    var tag = getTagMethod.Invoke(file, new[] { Id3Tag });
}

You should be doing something like this:你应该做这样的事情:

private void method()
{
    var assembly = Assembly.Load("taglib");
    var type = assembly.GetType("namespace.File"); // namespace qualified class name
    // assuming you only have one Create method, otherwise use reflection to resolve overloads
    var method = type.GetMethod("Create");

    dynamic file = method.Invoke(null, new[] { "C:\\temp\\some.mp3" }); // null for static methods
    var tag = file.GetTag(TagLib.TagTypes.Id3v2); // not sure if you can pass those params, 
                                                  // may be do reflection to get them too
}

Kindly rethink if you want it to be dynamic.如果您希望它是动态的,请重新考虑。 If you can reference the dll then you can still get the benefits of strong typing.如果您可以引用 dll,那么您仍然可以获得强类型的好处。

Save it as object.将其另存为对象。

object file = LibFile.Create(fi.FullName);

Should work.应该管用。

Dynamic loading dlls works much different.动态加载 dll 的工作方式大不相同。

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

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