开发者

Using an embedded DLL?

Is there any detailed guide on how to use a resource embedded dll within a c# source? All the guides I find on Google don't seem to help much. It's all "make a new class" or "ILMerge" this and ".NETZ" that. But I'm not sure on how to use the ILMerge and .NETZ stuff, and the guides on classes leave out what to do after making the class file, since I find nothing new after doing so. For example, this. After adding the class and function, I have no idea on how to reach out to get the dll from my resources.

So, to be specific, what I'm looking for is a guide on how to use a .dll file that was embedded into开发者_JAVA百科 Resources to be able to call a class, without and parts left out. Please keep in mind that I am not very experienced with C# coding. Thanks in advance. :D

PS. Try not to use those big words. I tend to get lost easily.


You can get a Stream to the DLL using Assembly.GetManifestResourceStream, but in order to do anything with it you'll either need to load it into memory and call Assembly.Load, or extract it to the file system (and then quite possibly still call Assembly.Load or Assembly.LoadFile, unless you've actually already got a dependency on it).

After loading the assembly you'd have to use reflection to create instances of classes or call methods etc. All of this is quite fiddly - and in particular I can never remember the situations in which to call the various overloads of Assembly.Load (or similar methods). Jeff Richter's "CLR via C#" book would be a useful resource to have at your desk.

Could you give more information about why you need to do this? I've used manifest resources for various things, but never to include code... is there any reason you can't ship it alongside your executable?

Here's a complete example, albeit without error checking:

// DemoLib.cs - we'll build this into a DLL and embed it
using System;

namespace DemoLib
{   
    public class Demo
    {
        private readonly string name;

        public Demo(string name)
        {
            this.name = name;
        }

        public void SayHello()
        {
            Console.WriteLine("Hello, my name is {0}", name);
        }
    }
}

// DemoExe.cs - we'll build this as the executable
using System;
using System.Reflection;
using System.IO;

public class DemoExe
{
    static void Main()
    {
        byte[] data;
        using (Stream stream = typeof(DemoExe).Assembly
               .GetManifestResourceStream("DemoLib.dll"))
        {
            data = ReadFully(stream);
        }

        // Load the assembly
        Assembly asm = Assembly.Load(data);

        // Find the type within the assembly
        Type type = asm.GetType("DemoLib.Demo");

        // Find and invoke the relevant constructor
        ConstructorInfo ctor = type.GetConstructor(new Type[]{typeof(string)});
        object instance = ctor.Invoke(new object[] { "Jon" });

        // Find and invoke the relevant method
        MethodInfo method = type.GetMethod("SayHello");
        method.Invoke(instance, null);
    }

    static byte[] ReadFully(Stream stream)
    {
        byte[] buffer = new byte[8192];
        using (MemoryStream ms = new MemoryStream())
        {
            int bytesRead;
            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, bytesRead);
            }
            return ms.ToArray();
        }
    }
}

Building the code:

> csc /target:library DemoLib.cs
> csc DemoExe.cs /resource:DemoLib.dll


You might need to use ILMerge. Looks like it will solve the problem naturally for you.

http://research.microsoft.com/en-us/people/mbarnett/ILMerge.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜