13,007
回編集
275行目: | 275行目: | ||
== サンプルコード == | == サンプルコード == | ||
==== | ==== ポインタのマーシャリング ==== | ||
例えば、C++ DLLから次のような関数がエクスポートされているとする。<br> | 例えば、C++ DLLから次のような関数がエクスポートされているとする。<br> | ||
<source lang="c++"> | <source lang="c++"> | ||
323行目: | 323行目: | ||
なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br> | なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br> | ||
<br> | <br> | ||
==== 配列のマーシャリング ==== | |||
このセクションでは、C# EXEからC++ DLLへ配列を渡す方法を記載する。<br> | |||
<br> | |||
まず、以下にC++ DLLを記述する。<br> | |||
<source lang="c++"> | |||
// SampleDLL.h | |||
#pragma once | |||
==== | int __stdcall SampleArray(int array[], int length); | ||
</source> | |||
<br> | |||
<source lang="c++"> | |||
// SampleDll.cpp | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include "SampleDll.h" | |||
void __stdcall SampleArray(int array[], int length) | |||
{ | |||
for (int i = 0; i < length; i++) | |||
{ | |||
std::cout << array[i] << std::endl; | |||
} | |||
} | |||
</source> | |||
<br> | |||
<source lang="c++"> | |||
// モジュール定義ファイル | |||
// SampleDll.def | |||
LIBRARY SampleDll | |||
EXPORTS | |||
; 公開する関数名をリストアップ | |||
SampleArray @1 | |||
</source> | |||
<br> | |||
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br> | |||
<br> | |||
手順としては、以下の処理の流れとなる。<br> | |||
# C# EXEでマネージド配列(C# EXEの配列)を定義する。 | |||
# C# EXEにおいて、アンマネージド配列(C++ DLLの配列)のメモリを確保する。 | |||
# マネージド配列の内容を、上記で確保したアンマネージド配列のメモリにコピーする。 | |||
# C++ DLLの関数を実行する時、ポインタを渡す。 | |||
# 使用したアンマネージド配列のメモリを解放する。 | |||
<br> | |||
<source lang="c#"> | |||
namespace SampleEXE | |||
{ | |||
[DllImport("SampleDll.dll", CallingConvention = CallingConvention.Cdecl)] | |||
static extern void SampleArray(IntPtr array, int length); | |||
static void Main() | |||
{ | |||
// 配列の定義 | |||
var array = new int[Length] { 0, 1, 2, 3, 4 }; | |||
// アンマネージド配列のメモリの確保 | |||
IntPtr ptrRet = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * array.Length); | |||
// マネージド配列をアンマネージドにコピーする | |||
Marshal.Copy(array, 0, ptrRet, array.Length); | |||
// C++ DLLに配列を渡す(ポインタを渡す) | |||
SampleArray(ptrRet, array.Length); | |||
// アンマネージドメモリの解放 | |||
Marshal.FreeCoTaskMem(ptrRet); | |||
} | |||
} | |||
</source> | |||
<br> | |||
==== 構造体のマーシャリング ==== | |||
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br> | C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br> | ||
<br> | <br> | ||
561行目: | 634行目: | ||
} | } | ||
</source> | </source> | ||
<br> | |||
==== 関数ポインタのマーシャリング ==== | |||
==== | |||
このセクションでは、C# EXEからC++ DLLへコールバック関数を渡す方法を記載する。<br> | このセクションでは、C# EXEからC++ DLLへコールバック関数を渡す方法を記載する。<br> | ||
<br> | <br> |