MFCDLL内の関数をC#で呼び出す
過去の資産をC#で利用したい。
その基本的なやり方を示します。
MFCDLLのプロジェクトを作成し、
apiModule.cppを追加し下記のように記述します。
defファイルに関数名を記述します。
apiModule.cpp
#include "StdAfx.h" void WINAPI Dll_ShowMessage(const CString &str) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ::AfxMessageBox(str); return; } void WINAPI Dll_ShowInt(int num) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString str; str.Format(_T("%d\n"), num); ::AfxMessageBox(str); }
defファイル
; mfcDllTest.def : DLL のモジュール パラメータを宣言します。 LIBRARY "mfcDllTest" EXPORTS ; 明示的なエクスポートはここへ記述できます Dll_ShowMessage Dll_ShowInt
これでビルドすると普通にdllが作成されます。
ただ、ユニコードでビルドしたのかマルチバイトでビルド
したのか気に留めておく必要があります。
次はC#での呼び出し方を示します。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace dllImportTest { public partial class TestForm : Form { public TestForm() { InitializeComponent(); } [DllImport("mfcDllTest.dll", CharSet=CharSet.Auto)] private extern static void Dll_ShowMessage(ref string str); [DllImport("mfcDllTest.dll", CharSet=CharSet.Auto)] private extern static void Dll_ShowInt(int num); private void button1_Click(object sender, EventArgs e) { string str = "test"; Dll_ShowMessage(ref str); Dll_ShowInt(10); } } }
"CharSet=CharSet.Auto"をつけていないと、
C#側でユニコードをマルチバイトにデフォルトで変換してしまいます。
C#側でも、MFCDLL側でもユニコードだから問題ないかなと
思い込んでいたら見事に嵌りました。
参照
http://www.atmarkit.co.jp/fdotnet/dotnettips/025w32string/w32string.html