これは何?
マネージドコードからアンマネージドコードのdllを呼ぶ、つまり .net framework を挟んだコードから挟まないコードのdllを呼ぶ方法の一つとして、P Invokeという方法があります。
ここでは、C++ で書かれた dll を、C# で PInvokeで呼ぶサンプルをしめします。
環境は以下の通りです。
- .NET Framework 4.7
- Visual Studio 2017
- Windows 10
呼び出される側の DLL
言語はC++です。
#include <Windows.h>
#include "BasicMath.h"
extern "C"
_declspec(dllexport) int half(int n){
return n / 2;
}
このコードで mymath.dll を作ります。
呼び出す実行ファイル側
マネージドコード側の C# です。できた mymath.dll 内の half 関数を呼び出します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace PInvok_caller
{
class Program
{
static void Main(string[] args)
{
int ret = half(10);
Console.WriteLine($"{ret}");
Console.ReadKey();
}
[DllImport("myath.dll", CallingConvention = CallingConvention.StdCall )]
static extern int half(int n);
}
}
コンソールに 5 と表示されると思います。
躓いたところ
[DllImport("mymath.dll")]
static extern int half(int n);
としたところ以下のようなエラーが出た。
PInvoke 関数 'PInvok_caller!PInvok_caller.Program::half' がスタックを不安定にしています。PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。呼び出し規約、および PInvoke シグネチャのパラメーターがターゲットのアンマネージ シグネチャに一致していることを確認してください。
アンマネージドコードの実行が厳格化されたようだ。以下のように変更。
[DllImport("mymath.dll", CallingConvention = CallingConvention.StdCall )]
static extern int half(int n);