LoginSignup
42
55

More than 1 year has passed since last update.

【C#】C#で作成したDLLをC#で呼ぶ(静的/動的)

Last updated at Posted at 2019-04-04

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

C#で作ったDLLを、C#で使いたい。

呼ばれる側C#(=DLL)

[VisualC#] > [Windowsデスクトップ]の中の[クラスライブラリ(.NET Framework)]を選択し、プロジェクトを作成する。
image.png

デフォルトで、下記のようなコードが生成される。

class1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class Class1
    {
    }
}

ここに、DLLで行いたい処理を記述する。
今回は、下記のようにした。

MyCsDllClass.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DllTestCs
{
    public class MyCsDllClass
    {
        public List<MyData> DataList = new List<MyData>();

        /// <summary>
        /// staticなメソッド。ただの足し算を行う。
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static int Add(int a, int b) => a + b;

        /// <summary>
        /// データリストに引数のデータを追加する。
        /// 追加後のデータリストの件数を返す。
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public int AddMyData(MyData data)
        {
            if (data != null)
            {
                DataList.Add(data);
            }

            return DataList.Count;
        }

        /// <summary>
        /// 引数で指定したindexを持つデータがリスト内にあればそれを返す。
        /// 無ければnullを返す。
        /// </summary>
        /// <param name="serachIndex"></param>
        /// <returns></returns>
        public MyData DataSearch(int serachIndex) => DataList.FirstOrDefault(x => x.index == serachIndex);
    }

    /// <summary>
    /// お試しデータのクラス。
    /// </summary>
    public class MyData
    {
        public int index;
        public double data;
    }
}

呼ぶ側C#(=アプリ)

まず、呼び出したいアプリ側のプロジェクトの「参照」に、上で作成したDLLを追加する。

image.png

image.png

参照を追加したら、そのDLLに含まれるクラスやメソッドを使用し、コーディングを行う。今回は、下記のようにした。

Program.cs
using DllTestCs;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // C#のDLLを呼ぶ(プロジェクトの参照に、DLLを追加し、このファイルの上にusingを追加)
            int a = MyCsDllClass.Add(1, 2);
            var mcdc = new MyCsDllClass();
            mcdc.AddMyData(new MyData() { index = 1, data = 1.1 });
            mcdc.AddMyData(new MyData() { index = 2, data = 2.2 });
            mcdc.AddMyData(new MyData() { index = 3, data = 3.3 });
            var result = mcdc.DataSearch(2);
            var result2 = mcdc.DataSearch(5);
        }
    }
}

備考

  • C#は、DLLを作る時も呼ぶときも、C++よりもかなり簡単に作れて呼べる。(普通にクラスを作って、呼ぶ側で参照に追加するだけ)
  • C++で作成したDLLをC++で呼ぶときと同じで、C#でDLLを呼ぶときも「動的」に呼べるらしい。(未検証)必要に迫られていないので、そのうちやり方確認したい。

コード

動的呼び出し(19/04/05追記)

動的に呼び出すには、下記のようにする。

動的呼び出し側サンプル.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CSharpConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            var asm = Assembly.LoadFrom("CSharpDll.dll");       // アセンブリの読み込み
            var module = asm.GetModule("CSharpDll.dll");        // アセンブリからモジュールを取得
            var Person = module.GetType("CSharpDll.Person");    // 利用するクラス(or 構造体)を取得

            if (Person != null)
            {
                // CSharpDll.Personクラスをインスタンス化.
                // コンストラクタへ引数を渡すことも可能.
                dynamic p1 = Activator.CreateInstance(Person, "Aiueo", 29);    

                // dynamicで受けているので, 面倒なプロパティ取得やメソッド取得を省略できる.
                Console.WriteLine($"name= {p1.Name}");
                Console.WriteLine($"age= {p1.Age}");
                Console.WriteLine(p1.ToString());
            }

            Console.ReadKey();
        }
    }
}
dll側サンプル.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpDll
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Person() : this("", 0) { }
        public Person(string name, int age) => (Name, Age) = (name, age);

        public override string ToString() => $"{Name} ({Age})";
    }
}

通常、動的な呼び出しは行わない。
使われるのは、プラグインを作る場合などにほとんど限られる。

42
55
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
55