13,007
回編集
454行目: | 454行目: | ||
<br> | <br> | ||
まず、以下にC++ DLLを記述する。<br> | まず、以下にC++ DLLを記述する。<br> | ||
< | <syntaxhighlight lang="c++"> | ||
// SampleDLL.h | // SampleDLL.h | ||
#pragma once | #pragma once | ||
int __stdcall | void __stdcall SampleArray01(int array[], int length); | ||
</ | int* __stdcall SampleArray02(int length); | ||
void __stdcall SampleArray03(int array[], int length); | |||
</syntaxhighlight> | |||
<br> | <br> | ||
< | <syntaxhighlight lang="c++"> | ||
// SampleDll.cpp | // SampleDll.cpp | ||
469行目: | 471行目: | ||
#include "SampleDll.h" | #include "SampleDll.h" | ||
void __stdcall | void __stdcall SampleArray01(int array[], int length) | ||
{ | { | ||
for (int i = 0; i < length; i++) | for (int i = 0; i < length; i++) | ||
476行目: | 478行目: | ||
} | } | ||
} | } | ||
</ | |||
int* __stdcall SampleArray02(int length) | |||
{ | |||
int* iary = new int[length]; | |||
for (int i = 0; i < length; i++) | |||
{ | |||
iary[i] = i; | |||
} | |||
return iary; | |||
} | |||
void __stdcall SampleArray03(int array[], int length) | |||
{ | |||
for (int i = 0; i < length; i++) | |||
{ | |||
arr[i] = i; | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | <br> | ||
< | <syntaxhighlight lang="c++"> | ||
// モジュール定義ファイル | // モジュール定義ファイル | ||
// SampleDll.def | // SampleDll.def | ||
486行目: | 508行目: | ||
EXPORTS | EXPORTS | ||
; 公開する関数名をリストアップ | ; 公開する関数名をリストアップ | ||
SampleArray01 @1 | |||
</ | SampleArray02 @2 | ||
SampleArray03 @3 | |||
</syntaxhighlight> | |||
<br> | <br> | ||
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br> | 次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br> | ||
498行目: | 522行目: | ||
# 使用したアンマネージド配列のメモリを解放する。 | # 使用したアンマネージド配列のメモリを解放する。 | ||
<br> | <br> | ||
< | <syntaxhighlight lang="c#"> | ||
namespace SampleEXE | namespace SampleEXE | ||
{ | { | ||
[DllImport("SampleDll.dll", CallingConvention = CallingConvention.Cdecl)] | [DllImport("SampleDll.dll", EntryPoint = "SampleArray01", CallingConvention = CallingConvention.Cdecl)] | ||
static extern void | static extern void _SampleArray01(IntPtr array, int length); | ||
[DllImport("SampleDll.dll", EntryPoint = "SampleArray02", CallingConvention = CallingConvention.Cdecl)] | |||
static extern IntPtr _SampleArray02(int length); | |||
[DllImport("SampleDll.dll", EntryPoint = "SampleArray03", CallingConvention = CallingConvention.Cdecl)] | |||
static extern IntPtr _SampleArray03(IntPtr array, int length); | |||
static void Main() | static void Main() | ||
{ | |||
SampleArray01(); | |||
SampleArray02(); | |||
SampleArray03(); | |||
} | |||
// SampleArray01 | |||
// 配列を渡す場合 | |||
private static void SampleArray01() | |||
{ | { | ||
// 配列の定義 | // 配列の定義 | ||
var array = new int[ | var array = new int[] { 0, 1, 2, 3, 4 }; | ||
// アンマネージド配列のメモリの確保 | // アンマネージド配列のメモリの確保 | ||
516行目: | 555行目: | ||
// C++ DLLに配列を渡す(ポインタを渡す) | // C++ DLLに配列を渡す(ポインタを渡す) | ||
_SampleArray01(ptrRet, array.Length); | |||
// アンマネージドメモリの解放 | // アンマネージドメモリの解放 | ||
Marshal.FreeCoTaskMem(ptrRet); | |||
} | |||
// SampleArray02 | |||
// 配列を受ける場合 (戻り値がint型ポインタ) | |||
private static void SampleArray02() | |||
{ | |||
// 空の配列の定義 | |||
int[] array = new int[5]; | |||
// 戻り値のポインタをIntPtrで受け取る | |||
IntPtr ptrRet = _SampleArray02(array.Length); | |||
// アンマネージド配列からマネージド配列へコピー | |||
Marshal.Copy(ptrRet, array, 0, array.Length); | |||
foreach(int n in array) | |||
{ | |||
Console.WriteLine(n + " "); | |||
} | |||
} | |||
// SampleArray03 | |||
// 配列を受ける場合 (引数がint型の配列) | |||
private static void SampleArray03() | |||
{ | |||
// 空の配列の定義 | |||
int[] array = new int[5]; | |||
// アンマネージド配列のメモリを確保 | |||
IntPtr ptrRet = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * array.Length); | |||
// 引数でポインタを渡す | |||
_SampleArray03(ptrRet, array.Length); | |||
// アンマネージド配列からマネージド配列へコピー | |||
Marshal.Copy(ptrRet, array, 0, array.Length); | |||
// アンマネージド配列のメモリを解放 | |||
Marshal.FreeCoTaskMem(ptrRet); | Marshal.FreeCoTaskMem(ptrRet); | ||
foreach(int n in array) | |||
{ | |||
Console.WriteLine(n + " "); | |||
} | |||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
<br> | <br> | ||
==== 文字列のマーシャリング ==== | ==== 文字列のマーシャリング ==== | ||
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br> | C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br> |