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クラスを使用した画面の描画の説明を予定しております。
それではまた。
コメント