13,230
回編集
細 (Wiki がページ「C Sharp(EXE)からC++(DLL)を呼ぶ」を「C Sharp - C++DLL」に、リダイレクトを残さずに移動しました) |
編集の要約なし |
||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
C# EXEからC++ DLLへ様々なデータ型の変数を渡したいときがある。<br> | C# EXEからC++ DLLへ様々なデータ型の変数を渡したいときがある。<br> | ||
<br> | <br><br> | ||
== サンプルコード == | |||
例えば、C++ DLLから次のような関数がエクスポートされているとする。<br> | 例えば、C++ DLLから次のような関数がエクスポートされているとする。<br> | ||
<source lang="c++"> | <source lang="c++"> | ||
| 7行目: | 9行目: | ||
</source> | </source> | ||
<br> | <br> | ||
上記の関数において、C# | 上記の関数において、C# EXEから使用する時は、第1引数の<code>char*</code>型は文字列なので、<code>string</code>型を渡す。<br> | ||
short* | 第2引数の<code>short*</code>型は、<code>IntPtr</code>型を渡す。(IntPtr型は汎用ポインタを表す型であり、void*型とほぼ同義)<br> | ||
<br> | <br> | ||
ただし、C#は厳しい型付け言語なので、曖昧さを解決するために変換メソッドを経由する必要がある。<br> | |||
<br> | |||
Marshal. | 具体的には、<code>IntPtr</code>型の変数に<code>Marshal.AllocHGlobal</code>関数で必要なサイズのメモリを確保して、それをC++ DLLに渡した後、<br> | ||
<br><br> | <code>Marshal.ReadInt16</code>関数(型によって異なる)等で変換した後、確保したメモリを<code>Marshal.FreeHGlobal</code>関数で解放するというプロセスを経る必要がある。<br> | ||
<br> | |||
以下の例では、C++ DLLを呼ぶC# EXEのソースコードを記述している。<br> | |||
<source lang="c#"> | <source lang="c#"> | ||
// DllImportを使用するために必要 | // DllImportを使用するために必要 | ||
| 35行目: | 36行目: | ||
</source> | </source> | ||
<br> | <br> | ||
<code>IntPtr</code>型の変数は様々なものが入る。<br> | |||
ただし、構造体を取得することもできるが、C# EXEで構造体を定義しなければならない。<br> | |||
ネイティブコードと.NET Frameworkでは型の管理方法が違うため、実際には型の相互変換(マーシャリング)が行われる。<br> | |||
<br> | |||
なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br> | |||
<br> | <br> | ||
<center>''' | <center>'''表. Windows APIの型と対応するC#の型'''</center> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
| 75行目: | 78行目: | ||
== サンプルコード == | == サンプルコード == | ||
C++ DLLの作成方法は[[ | C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br> | ||
<br> | |||
下記にもC++ DLLを記述する。<br> | 下記にもC++ DLLを記述する。<br> | ||
<source lang="c++"> | <source lang="c++"> | ||
| 86行目: | 90行目: | ||
void __stdcall SampleFunc05(SampleStruct *pStructure) | void __stdcall SampleFunc05(SampleStruct *pStructure) | ||
</source> | </source> | ||
<br> | |||
<source lang="c++"> | <source lang="c++"> | ||
SampleDll.cpp | SampleDll.cpp | ||
| 167行目: | 172行目: | ||
</source> | </source> | ||
<br> | <br> | ||
次に、C# | 次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br> | ||
文字列をC++ DLL側に渡す場合は、string型を使用する。<br> | 文字列をC++ DLL側に渡す場合は、string型を使用する。<br> | ||
文字列をC++ DLL側から返す場合は、string型ではなくStringBuilderクラスを使用する必要がある。<br> | 文字列をC++ DLL側から返す場合は、string型ではなくStringBuilderクラスを使用する必要がある。<br> | ||
| 310行目: | 315行目: | ||
</source> | </source> | ||
<br> | <br> | ||
<code>DllImport</code>属性には、DLLファイルのパスを指定する以外にも、下表のような引数を与えることができる。<br> | |||
他にも、細かい設定をするための引数が用意されているので、<code>DllImportAttribute</code>クラスで検索すること。<br> | |||
<center> | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
| 322行目: | 328行目: | ||
| EntryPoint || 呼び出すDLLエントリポイントの名前または序数を指定する。<br>DLLの関数名とC#上で使用する関数名を異なる名前にする時に指定する。 | | EntryPoint || 呼び出すDLLエントリポイントの名前または序数を指定する。<br>DLLの関数名とC#上で使用する関数名を異なる名前にする時に指定する。 | ||
|} | |} | ||
</center> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] | ||