【C#】C#からC言語のDLLの呼び出し&作成方法を詳しく説明します 第1回 【C#】【C/C++】【DLL】【初心者】【C# DLL呼び出し】

C#からC言語DLLの呼び出し方法 プログラム

C#からC言語で作成したDLLの呼び出し方法及び作成方法を詳しく説明していきます。

Visual Studio 2022を使用したDLL呼び出し元のC#プロジェクト作成、C言語のDLLプロジェクトの順で説明していきます。

このDLL作成はプロジェクト作成&デバッグ方法の説明が第一部、HSV色変換DLLの作成が第二部の二部構成で説明していきます。

DLL呼び出し元のC#プロジェクトの作成

Visual Studio 2022を起動して、赤枠の「新しいプロジェクトの作成」を選択して下さい。


新しいプロジェクトの作成では赤枠のコンボボックスの設定を「C#」、「Windows」、「デスクトップ」にし、「Windows フォーム アプリケーション(.NET Framework)」を選択後、次へボタンを押下して下さい。


「新しいプロジェクトを構成します」では赤枠のプロジェクト名を「hsv_test」、場所はデスクトップ等の任意の場所に作成してもかまいません。

作成ボタンの押下でプロジェクトが作成されます。

「新しいプロジェクトを構成します」では赤枠のプロジェクト名を「hsv_test」、場所はデスクトップ等の任意の場所に作成してもかまいません。

作成ボタンの押下でプロジェクトが作成されます。


作成されたプロジェクトはこの様になります。


右側のソリューションエクスプローラーの「hsv_test」を右クリックしてプロパティを選択して下さい。

左側のビルドを選択後、赤枠の「32ビットを選ぶ」のチェックを外してください。


フォームにラベルを1つ配置して下さい。

ここで一度、ビルドを実行してください。

C言語のDLLプロジェクトの作成

C#プロジェクト作成と同様にVisual Studio 2022を起動して、新しいプロジェクトを作成して下さい。

赤枠のコンボボックスの設定を「C++」、「Windows」、「ライブラリ」にし、「ダイナミック リンク ライブラリ」選択後、次へボタンを押下して下さい。


「新しいプロジェクトを構成します」では赤枠のプロジェクト名を「msf_util」、場所はC#プロジェクトを作成した場所と同じ場所を指定して下さい。

作成ボタンの押下でプロジェクトが作成されます。


プロジェクトの作成後、赤枠の「dllmain.cpp」を削除して下さい。

モジュール定義ファイル(.def)を使用してDLLエントリーポイントをエクスポートしますので「dllmain.cpp」は必要ありません。


ヘッダーファイルを作成します。

ソリューションエクスプローラーの「ヘッダーファイル」を右クリック、赤枠の「追加」、「新しい項目」を選択後、「HSV_ChangeColor.h」を作成して下さい。


作成後、以下のコードを入力して下さい。

#pragma once

#include <windows.h>

//----- HSV_ChangeColor()引き数の構造体 -----
typedef struct {
	WORD	angle;								//HSV 変換角度
	void* src_bmp_ptr;							//source BMP ポインター
	void* byte_buff;							//HSV変換済みデータ ポインター
} HSV_VhangeColor_Wk;

INT16 HSV_ChangeColor(HSV_VhangeColor_Wk* in_ptr);

この構造体はC#から渡される引き数を受ける為の構造体になります。

C#からはマネージドコードで渡されますので、変数は実体、配列はSAFEARRAYポインターで処理を行います。

C#側でアンマネージド配列を作成してから渡すこともできますが、DLLの呼び出し前にアンマネージド配列へのコピー、DLL呼び出し後のマネージド配列へのコピーが必要となり、無駄なメモリーコピーが発生してしまいます。

基本的にはマネージド配列を渡してSAFEARRAYポインターでの処理でOKです。


次はソリューションエクスプローラーの「ソース ファイル」に「HSV_ChangeColor.cpp」を作成して以下のコードを入力して下さい。

作成方法はヘッダーファイルの作成と同様の手順となります。

#include "pch.h"
#include "HSV_ChangeColor.h"

//************************************************
//*
//* INT16 HSV_ChangeColor(HSV_ChangeColor_Wk *in_ptr)
//*
//* HSV色変換を行う
//*
//* in.		HSV_ChangeColor_Wk	*in_ptr							画像変換ワークポインター
//*
//* out.	INT16												0=成功 : 1=失敗
//*
//************************************************

INT16 HSV_ChangeColor(HSV_VhangeColor_Wk* in_ptr)
{
	in_ptr->angle++;



	return 0;
}


デバッグ用として18行目にブレークポイントを設定して下さい。


DLLのエントリーポイントを指定するモジュール定義ファイルを作成します。

ソリューションエクスプローラーの「ソース ファイル」に「msf_util.def」を作成し、以下のコードを入力して下さい。

LIBRARY "msf_util"
 EXPORTS
 HSV_ChangeColor


このモジュール定義でC#から「HSV_ChangeColor(…)」でDLL呼び出しが可能となります。

次はプロパティを設定します。ソリューションエクスプローラーの「msf_util」を右クリックし「プロパティ」を選択して下さい。

構成プロパティ・全般、赤枠の「出力ディレクトリ」をC#プロジェクトの「..\..\hsv_test\hsv_test\bin\Debug\」に設定して下さい。※「..\..\hsv_test\hsv_test」は自分で作成したプロジェクトのパスに変更して下さい。

また、「出力ディレクトリ」を参照から設定した場合は「\Debug」になっているので、最後に「\」を追加して下さい。


構成プロパティ・詳細、赤枠の「共通言語ランタイムサポート」を「.NET Framework ランタイム サポート(/clr)」、「.NET Framework 対象バージョン」を「v4.8」、「マネージド インクリメンタル ビルドを有効にする」を「はい」に設定して下さい。


構成プロパティ・デバッグ、赤枠の「コマンド」をC#プロジェクトの「hsv_test.exe」を指定して下さい。

※C#プロジェクトに「hsv_test.exe」が存在しない場合はC#プロジェクトのビルドを実行して下さい。


構成プロパティ・リンカー、赤枠の「モジュール定義ファイル」に「msf_util.def」と入力して下さい。

「msf_util.def」は「ソース ファイル」フォルダに作成したファイルで、この記述をしない場合はエントリーポイントが無いDLLが出来上がります。


C#プロジェクトのDLL呼び出しの実装

「hsv_test」プロジェクトに「Dll_Import」クラスファイルを作成し、以下のコードを入力して下さい。

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

#pragma warning disable 0649                   //CS0649のワーニングを消去(使用していないワーニングを消す)
namespace hsv_test
{
	public class Dll_Import
	{
		#region"HSV色変換"
		public struct HSV_ChangeColor_Wk
		{
			//C++DLL側でSAFEARRAYポインターで操作する場合は、[MarshalAs(UnmanagedType.SafeArray)]を省略してもOK
			//アンマネージドにする場合はマーシャルコピーでアンマネージド配列を作り、配列のポインターを渡す必要性あり
			//[MarshalAs(UnmanagedType.SafeArray)]
			public UInt16 angle;				//色変換角度(0 - 359)
			public byte[] src_bmp_ptr;			//変換元BMPデータ配列
			public byte[] dst_bmp_ptr;			//変換後BMPデータ配列(サイズ0の配列、例:dst_bmp_ptr = new byte[0];)
		}
		/// <summary>
		/// HSV色変換処理
		/// </summary>
		/// <param name="hsv_color_wk"></param>
		/// <returns></returns>
		[DllImport("msf_util.dll", EntryPoint = "HSV_ChangeColor")]
		public static extern Int16 HSV_ChangeColor(ref HSV_ChangeColor_Wk hsv_color_wk);
		#endregion
	}
}


Form1.cs[デザイン]のフォームコントロール画面をダブルクリックし、以下のソースコードを入力して下さい。

ソースコードは全てを記載していますが、「private void Form1_Load(object sender, EventArgs e)」内の入力でOKです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace hsv_test
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			Dll_Import.HSV_ChangeColor_Wk wk;

			wk.angle = 110;
			wk.src_bmp_ptr = new byte[0];
			wk.dst_bmp_ptr = new byte[0];
			Dll_Import.HSV_ChangeColor(ref wk);


			label1.Text = wk.angle.ToString();
		}
	}
}


変数のangleに「110」を入れてDLLを呼び出ししています。

DLL呼び出し後のangleを「label1」に表示するだけのプログラムになっています。

ここで一度ビルドして下さい。

C言語のDLLプロジェクトの実行

ようやくDLL呼び出しが実行できるようになりましたので実行してみましょう。

「msf_util」プロジェクトを実行してください。

設定したブレークポイントで停止するはずです。

in_ptr->angleに110が入っています。

この110はC#プロジェクト側から渡された数値です。


プログラムを実行すると「angle」がインクリメントされて111になります。

DLLからC#プロジェクトに処理が戻り画面に「111」表示されてるとDLL作成&デバッグの完了です。


ここまで出来れば後は中身の実装だけになります。

最初は分かりにくいと思いますが、一度出来てしまえば同じ方法でDLL作成を行う事が可能です。

次回はHSV色変換の実装を行います。

その後、Graphicsクラスを使用した画面の描画の説明を予定しております。

それではまた。

コメント

タイトルとURLをコピーしました