「ライブラリの基礎 - C++DLL」の版間の差分
ナビゲーションに移動
検索に移動
表1. Win32 APIでの型名と対応するC#の型
編集の要約なし |
編集の要約なし |
||
60行目: | 60行目: | ||
| BOOL (long) || bool (System.Boolean) || | | BOOL (long) || bool (System.Boolean) || | ||
|- | |- | ||
| CHAR (char) || char (System.Char) || | | CHAR (char) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder || | ||
|- | |- | ||
| WCHAR(wchar_t) || char (System.Char) || | | WCHAR(wchar_t) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder || | ||
|- | |- | ||
| LPSTR (char *, char[])<br>LPWSTR (wchar_t *, wchar_t[]) || string (System.String)<br>System.Text.StringBuilder || | | LPSTR (char *, char[])<br>LPWSTR (wchar_t *, wchar_t[]) || string (System.String)<br>System.Text.StringBuilder || |
2019年10月31日 (木) 13:09時点における版
概要
C# EXEからC++ DLLへ様々なデータ型の変数を渡したいときがある。
例えば、C++ DLLから次のような関数がエクスポートされているとする。
void WINAPI ConvertToShort(char *pstr, short *pret);
上記の関数において、C# EXEから使用するときは、char*型は文字列なのでstring型を渡す。
short*型はIntPtr型を渡す。(IntPtr型は汎用ポインタを表す型であり、void*型とほぼ同義)
但し、C#は厳しい型付け言語なので、曖昧さを解決するために変換メソッドを経由する必要がある。
具体的には、IntPtr型の変数にMarshal.AllocHGlobal関数で必要なサイズのメモリを確保して、それをC++ DLLに渡した後、
Marshal.ReadInt16関数(型によって異なる)等で変換した後、確保したメモリをMarshal.FreeHGlobal関数で解放するというプロセスを経る必要がある。
サンプルコード
下記に、C++ DLLを呼ぶC# EXEのソースコードを記載する。
// DllImportを使用するために必要
using System.Runtime.InteropServices;
[DllImport("DrsUtil.dll", EntryPoint = "ConvertToShort")]
extern static void _ConvertToShort(string pstr, IntPtr pret); //呼び出し元の名前変えちゃう
public static short ConvertToShort(string str)
{
IntPtr buffer = new IntPtr();
buffer = Marshal.AllocHGlobal(2); // 2バイトのメモリ確保
_ConvertToShort(str, buffer); // C++/DLLの関数を呼ぶ
short sval = Marshal.ReadInt16(buffer); // 変換
Marshal.FreeHGlobal(buffer); // メモリ開放
return sval;
}
IntPtr型の変数は様々なものが入るので、例えば、構造体を取得することも可能だが、C# EXEで構造体を定義しなければいけない。
WindowsのDLL(Win32 API)と.NET Frameworkでは型の管理方法が違うため、実際には型の相互変換(マーシャリング)が行われる。
尚、BOOL型の実体はLONG型と同じなので、boolの代わりにintを指定することも可能である。
APIの型名 (括弧内は対応するC言語の型) |
対応するC#の型 (括弧内は.NET Frameworkでの型名) |
備考 |
---|---|---|
HANDLE (void *) | System.IntPtr System.UIntPtr |
x86は4バイト x64は8バイト |
BYTE (unsigned char) | byte (System.Byte) | |
SHORT (short) | short (System.Int16) | |
WORD (unsigned short) | ushort (System.UInt16) | |
INT (int) LONG (long) |
int (System.Int32) | |
UINT (unsigned int) DWORD, ULONG (unsigned long) |
uint (System.UInt32) | |
BOOL (long) | bool (System.Boolean) | |
CHAR (char) | 文字を渡すとき char (System.Char) 文字を受け取るとき StringBuilder |
|
WCHAR(wchar_t) | 文字を渡すとき char (System.Char) 文字を受け取るとき StringBuilder |
|
LPSTR (char *, char[]) LPWSTR (wchar_t *, wchar_t[]) |
string (System.String) System.Text.StringBuilder |
|
LPCSTR (const char *, const char[]) LPCWSTR (const wchar_t *, const wchar_t[]) |
string (System.String) | |
FLOAT (float) | float (System.Single) | |
DOUBLE (double) | double (System.Double) |