もくじ
→https://tera1707.com/entry/2022/02/06/144447
やりたいこと
C#で作ったDLLを、C#で使いたい。
呼ばれる側C#(=DLL)
[VisualC#] > [Windowsデスクトップ]の中の[クラスライブラリ(.NET Framework)]を選択し、プロジェクトを作成する。
デフォルトで、下記のようなコードが生成される。
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を追加する。
参照を追加したら、その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})";
}
}
通常、動的な呼び出しは行わない。
使われるのは、プラグインを作る場合などにほとんど限られる。