「ライブラリの基礎 - C++DLL」の版間の差分

編集の要約なし
(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# EXEから使用するときは、char*型は文字列なのでstring型を渡す。<br>
上記の関数において、C# EXEから使用する時は、第1引数の<code>char*</code>型は文字列なので、<code>string</code>型を渡す。<br>
short*型はIntPtr型を渡す。(IntPtr型は汎用ポインタを表す型であり、void*型とほぼ同義)<br>
第2引数の<code>short*</code>型は、<code>IntPtr</code>型を渡す。(IntPtr型は汎用ポインタを表す型であり、void*型とほぼ同義)<br>
<br>
<br>
但し、C#は厳しい型付け言語なので、曖昧さを解決するために変換メソッドを経由する必要がある。<br>
ただし、C#は厳しい型付け言語なので、曖昧さを解決するために変換メソッドを経由する必要がある。<br>
具体的には、IntPtr型の変数にMarshal.AllocHGlobal関数で必要なサイズのメモリを確保して、それをC++ DLLに渡した後、<br>
<br>
Marshal.ReadInt16関数(型によって異なる)等で変換した後、確保したメモリをMarshal.FreeHGlobal関数で解放するというプロセスを経る必要がある。<br>
具体的には、<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>
下記に、C++ DLLを呼ぶC# EXEのソースコードを記載する。<br>
  <source lang="c#">
  <source lang="c#">
  // DllImportを使用するために必要
  // DllImportを使用するために必要
35行目: 36行目:
  </source>
  </source>
<br>
<br>
IntPtr型の変数は様々なものが入るので、例えば、構造体を取得することも可能だが、C# EXEで構造体を定義しなければいけない。<br>
<code>IntPtr</code>型の変数は様々なものが入る。<br>
WindowsのDLL(Win32 API)と.NET Frameworkでは型の管理方法が違うため、実際には型の相互変換(マーシャリング)が行われる。<br>
ただし、構造体を取得することもできるが、C# EXEで構造体を定義しなければならない。<br>
尚、BOOL型の実体はLONG型と同じなので、boolの代わりにintを指定することも可能である。<br>
ネイティブコードと.NET Frameworkでは型の管理方法が違うため、実際には型の相互変換(マーシャリング)が行われる。<br>
<br>
なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br>
<br>
<br>
<center>'''表1. Win32 APIでの型名と対応するC#の型'''</center>
<center>'''. Windows APIの型と対応するC#の型'''</center>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
75行目: 78行目:


== サンプルコード ==
== サンプルコード ==
C++ DLLの作成方法は[[DLLを作成する(MFC)|コチラを参照]]する。<br>
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# EXE側でC++ DLLを呼び出す方法を記述する。<br>
次に、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>
DllImport属性には、DLLファイルのパスを指定する以外に次のような引数を与えることもできる。<br>
<code>DllImport</code>属性には、DLLファイルのパスを指定する以外にも、下表のような引数を与えることができる。<br>
これ他にも細かい設定をするための引数が用意されているので、DllImportAttributeクラスで検索すること。<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]]