📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の12版が非表示)
10行目: 10行目:
== DllImport属性 ==
== DllImport属性 ==
<code>DLLImport</code>属性は、DLLエントリポイントを定義する関数を記述することで、DLLファイルに定義された関数を呼び出すことができる。<br>
<code>DLLImport</code>属性は、DLLエントリポイントを定義する関数を記述することで、DLLファイルに定義された関数を呼び出すことができる。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  [ DllImport( "DLL名" ) ]
  [ DllImport( "DLL名" ) ]
  </source>
  </syntaxhighlight>
<br>
<br>
また、DLLファイルに定義された関数を、関数名または序数で指定するには、<code>DllImport</code>属性の<code>EntryPoint</code>フィールドを使用する。<br>
また、DLLファイルに定義された関数を、関数名または序数で指定するには、<code>DllImport</code>属性の<code>EntryPoint</code>フィールドを使用する。<br>
19行目: 19行目:
<br>
<br>
以下の例では、<code>EntryPoint</code>フィールドを使用して、<code>MessageBoxA</code>をMsgBoxAに置き換える方法を示している。<br>
以下の例では、<code>EntryPoint</code>フィールドを使用して、<code>MessageBoxA</code>をMsgBoxAに置き換える方法を示している。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  using System;
  using System;
  using System.Runtime.InteropServices;
  using System.Runtime.InteropServices;
28行目: 28行目:
     internal static extern int MsgBoxA(IntPtr hWnd, string lpText, string lpCaption, uint uType);
     internal static extern int MsgBoxA(IntPtr hWnd, string lpText, string lpCaption, uint uType);
  }
  }
  </source>
  </syntaxhighlight>
<br>
<br>
また、以下の例では、DLLファイルに定義された関数を序数で指定している。<br>
また、以下の例では、DLLファイルに定義された関数を序数で指定している。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  [DllImport("DllName", EntryPoint = "Functionname")]
  [DllImport("DllName", EntryPoint = "Functionname")]
  [DllImport("DllName", EntryPoint = "#123")]  // 序数を使用するには、序数値の前にシャープ記号#を付ける必要がある
  [DllImport("DllName", EntryPoint = "#123")]  // 序数を使用するには、序数値の前にシャープ記号#を付ける必要がある
  </source>
  </syntaxhighlight>
<br>
<br>
<code>DllImport</code>属性には、DLLファイル名を指定する以外にも、下表のような引数を与えることができる。<br>
<code>DllImport</code>属性には、DLLファイル名を指定する以外にも、下表のような引数を与えることができる。<br>
93行目: 93行目:
以下の例では、呼び出し規約を適用する方法をCdeclとしている。<br>
以下の例では、呼び出し規約を適用する方法をCdeclとしている。<br>
これは、呼び出し元がスタックをクリーンアップするために使用する必要がある。<br>
これは、呼び出し元がスタックをクリーンアップするために使用する必要がある。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  using System;
  using System;
  using System.Runtime.InteropServices;
  using System.Runtime.InteropServices;
119行目: 119行目:
     }
     }
  }
  }
  </source>
  </syntaxhighlight>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
[https://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.callingconvention.aspx CallingConvention 列挙型 (System.Runtime.InteropServices) | MSDN]<br>
[https://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.callingconvention.aspx CallingConvention 列挙型 (System.Runtime.InteropServices) | MSDN]<br>
126行目: 126行目:
== StructLayout属性 ==
== StructLayout属性 ==
StructLayout属性とは、クラスまたは構造体のデータメンバを、メモリ内でどのように配置するかを表す。<br>
StructLayout属性とは、クラスまたは構造体のデータメンバを、メモリ内でどのように配置するかを表す。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  [ StructLayout( LayoutKind列挙 ) ]
  [ StructLayout( LayoutKind列挙 ) ]
  </source>
  </syntaxhighlight>
<br>
<br>
下表に、LayoutKind列挙子を示す。<br>
下表に、LayoutKind列挙子を示す。<br>
158行目: 158行目:
</center>
</center>
<br>
<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  [StructLayout( LayoutKind.Sequential )]
  [StructLayout( LayoutKind.Sequential )]
  public struct Position
  public struct Position
166行目: 166行目:
     public double z;
     public double z;
  }
  }
  </source>
  </syntaxhighlight>
<br>
<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
179行目: 179行目:
<br>
<br>
以下の例では、UInt32型はCLSに準拠しないため、<code>CLSCompliant(false)</code>と指定する必要がある。<br>
以下の例では、UInt32型はCLSに準拠しないため、<code>CLSCompliant(false)</code>と指定する必要がある。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  [CLSCompliant( false )]
  [CLSCompliant( false )]
  public int SetValue( UInt32 value );
  public int SetValue( UInt32 value );
  </source>
  </syntaxhighlight>
<br>
<br>
以下の例では、CLSCompliantAttribute属性をアセンブリ全体に適用する。<br>
以下の例では、CLSCompliantAttribute属性をアセンブリ全体に適用する。<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  using System;
  using System;
  [assembly: CLSCompliant(true)]
  [assembly: CLSCompliant(true)]
  </source>
  </syntaxhighlight>
<br>
<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
206行目: 206行目:
詳細は、以下のMSDNのWebサイトを参照すること。<br>
詳細は、以下のMSDNのWebサイトを参照すること。<br>
[https://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.marshalasattribute.aspx MarshalAsAttribute クラス (System.Runtime.InteropServices) | MSDN]<br>
[https://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.marshalasattribute.aspx MarshalAsAttribute クラス (System.Runtime.InteropServices) | MSDN]<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  // パラメータへの適用
  // パラメータへの適用
  public void M1([MarshalAs(UnmanagedType.LPWStr)]string msg)
  public void M1([MarshalAs(UnmanagedType.LPWStr)]string msg)
226行目: 226行目:
     return "Hello World";
     return "Hello World";
  }
  }
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


242行目: 242行目:
</center>
</center>
<br>
<br>
  <source lang="csharp">
  <syntaxhighlight lang="csharp">
  void Method([in] int[] array);
  void Method([in] int[] array);
  </source>
  </syntaxhighlight>
<br><br>
<br><br>


== C#のデータ型とWindows APIのデータ型 ==
== C#のデータ型とC++のデータ型 ==
<center>
<center>
{| class="wikitable"
{| class="wikitable" | style="background-color:#fefefe;"
|-
! style="background-color:#66CCFF;" | Windows APIのデータ型<br>(括弧内は対応するC言語の型)
! style="background-color:#66CCFF;" | 対応するC#のデータ型<br>(括弧内は.NET Frameworkでの型名)
! style="background-color:#66CCFF;" | 備考
|-
| HANDLE (void *)<br>HMODULE<br>HINSTANCE<br>HWND<br>HWM<br>HGDIOBJ<br>HDC || System.IntPtr<br>System.UIntPtr || x86は4バイト<br>x64は8バイト
|-
| char 配列名 [配列サイズ] || MarshalAs(UnmanagedType.ByValTStr, SizeConst = 配列のサイズ)] public string 配列名 ||
|-
| char ** || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||
|-
|-
! Windows APIのデータ型<br>(括弧内は対応するC言語の型) !! 対応するC#のデータ型<br>(括弧内は.NET Frameworkでの型名) !! 備考
| BYTE (unsigned char)<br>UCHAR || byte (System.Byte) || UCHAR型は、C#のstring型およびIntPtr型でも可能。
|-
|-
| HANDLE (void *) || System.IntPtr<br>System.UIntPtr || x86は4バイト<br>x64は8バイト
| BYTE[] (unsigned char *)<br>PBYTE (byte *) || System.Byte[]<br>[MarshalAs(UnmanagedType.LPArray)] byte[]<br>[MarshalAs(UnmanagedType.LPArray)] Intptr ||
|-
|-
| BYTE (unsigned char) || byte (System.Byte) ||  
| unsigned char & || ref byte ||  
|-
|-
| SHORT (short) || short (System.Int16) ||  
| SHORT (short) || short (System.Int16) ||  
261行目: 271行目:
| WORD (unsigned short) || ushort (System.UInt16) ||  
| WORD (unsigned short) || ushort (System.UInt16) ||  
|-
|-
| INT (int)<br>LONG (long) || int (System.Int32) ||  
| INT (int)<br>LONG (long)<br>DWORDLONG<br>HPARAM<br>LPARAM<br>WPARAM || int (System.Int32) || System.Int16でも取得できる可能性がある。
|-
| UINT (unsigned int)<br>DWORD (unsigned long)<br>ULONG (unsigned long) || uint (System.UInt32) ||
|-
| DECIMAL || decimal (System.Decimal) ||  
|-
|-
| UINT (unsigned int)<br>DWORD, ULONG (unsigned long) || uint (System.UInt32) ||  
| bool || bool (System.Boolean) ||  
|-
|-
| BOOL (long) || bool (System.Boolean) ||  
| BOOL (long) || bool (System.Boolean) ||  
269行目: 283行目:
| CHAR (char) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder ||  
| CHAR (char) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder ||  
|-
|-
| WCHAR(wchar_t) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder ||  
| WCHAR (wchar_t) || 文字を渡すとき<br>char (System.Char)<br>文字を受け取るとき<br>StringBuilder ||  
|-
|-
| LPSTR (char *, char[])<br>LPWSTR (wchar_t *, wchar_t[]) || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||  
| PCAHR (char *)<br>LPSTR (char *, char[])<br>LPWSTR (wchar_t *, wchar_t[]) || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||  
|-
|-
| LPCSTR (const char *, const char[])<br>LPCWSTR (const wchar_t *, const wchar_t[]) || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||  
| LPCSTR (const char *, const char[])<br>LPCWSTR (const wchar_t *, const wchar_t[]) || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||  
|-
| LPTSTR (char * または wchar_t *) || 文字を渡すとき<br>[MarshalAs(UnmanagedType.LPTStr)] string<br>文字を受け取るとき<br>System.Text.StringBuilder ||
|-
| LPCTSTR (const char * または const wchar_t *) || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||
|-
| BSTR || 文字を渡すとき<br>string (System.String)<br>文字を受け取るとき<br>System.Text.StringBuilder ||
|-
|-
| FLOAT (float) || float (System.Single) ||  
| FLOAT (float) || float (System.Single) ||  
|-
| float <配列名>[]<br>float <配列名> [配列サイズ] || float[]<br>ref float[] ||
|-
|-
| DOUBLE (double) || double (System.Double) ||  
| DOUBLE (double) || double (System.Double) ||  
|-
| double <配列名>[]<br>double <配列名> [配列サイズ] || double[]<br>ref double[] ||
|-
| VARIANT || System.Object ||
|-
| COLORREF || uint ||
|-
| GUID || Guid ||
|-
| struct <構造体名> <変数名> || ref <構造体名> <変数名> ||
|-
| struct <構造体名> || public struct <構造体名> || <u>out <構造体名></u>であらかじめ構造体をインスタンス化して、変数名を宣言する。
|}
|}
</center>
</center>
<br><br>
<br><br>


== サンプルコード ==
== 整数型および浮動小数点型のマーシャリング ==
==== 整数型および浮動小数点型のマーシャリング ====
==== Linux ====
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
下記に、Linux向けC++ライブラリを記述する。<br>
<syntaxhighlight lang="c++">
// SampleLib.cpp
#include <cstdio>
#include <cstring>
extern "C" int __attribute__((visibility("default"))) SampleFunc01(int a)
{
    printf(--<SampleDll:SampleFunc01>--\r\n");
    printf("a = %d\r\n", a);
    printf("---------------------------\r\n");
    return 10;
}
extern "C" double __attribute__((visibility("default"))) SampleFunc02(double a)
{
    printf("--<SampleDll:SampleFunc02>--\r\n");
    printf("a = %f\r\n", a);
    printf("---------------------------\r\n");
    return 3.14;
}
</syntaxhighlight>
<br>
==== Windows ====
Windows向けC++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
<br>
<br>
下記にもC++ DLLを記述する。<br>
下記に、C++ DLLを記述する。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // SampleDLL.h
  // SampleDLL.h
331行目: 392行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== Linux / Windows ====
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
<br>
<br>
342行目: 404行目:
     class Program
     class Program
     {
     {
       [DllImport("SampleDLL.dll")]
       [DllImport("SampleDLL.dll")] // Windows
      [DllImport("SampleLib.so")]  // Linux
       private static extern int SampleFunc01(int a);
       private static extern int SampleFunc01(int a);
   
   
       [DllImport("SampleDLL.dll")]
       [DllImport("SampleDLL.dll")] // Windows
      [DllImport("SampleLib.so")]  // Linux
       private static extern double SampleFunc02(double a);
       private static extern double SampleFunc02(double a);
   
   
363行目: 427行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br><br>
==== ポインタのマーシャリング ====
 
== ポインタのマーシャリング ==
例えば、C++ DLLから次のような関数がエクスポートされているとする。<br>
例えば、C++ DLLから次のような関数がエクスポートされているとする。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
456行目: 521行目:
<br>
<br>
なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br>
なお、Windows APIではBOOL型の実体はLONG型なので、.NET Frameworkではboolの代わりにintを指定することも可能である。<br>
<br>
<br><br>


==== 配列のマーシャリング ====
== 配列のマーシャリング ==
このセクションでは、C# EXEからC++ DLLへ配列を渡す方法を記載する。<br>
このセクションでは、C# EXEからC++ DLLへ配列を渡す方法を記載する。<br>
<br>
<br>
614行目: 679行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br><br>


==== 文字列のマーシャリング (1) ====
== 文字列のマーシャリング (1) ==
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
<br>
<br>
740行目: 805行目:
       }
       }
     }
     }
}
</syntaxhighlight>
<br><br>
== 文字列のマーシャリング (2) ==
==== Linux ====
Linux向けC++ライブラリを記述する。<br>
<syntaxhighlight lang="c++">
// SampleLib.cpp
#include <cstdio>
extern "C" double __attribute__((visibility("default"))) SampleFunc01(int a)
{
    printf("--<SampleDll:SampleFunc01>--\r\n");
    printf("a = %d\r\n", a);
    printf("---------------------------\r\n");
    return 3.14;
}
extern "C" void __attribute__((visibility("default"))) SampleFunc02(int a, char *pstr)
{
    printf("--<SampleDll:SampleFunc02>--\r\n");
    printf("[%d] %s\r\n", a, pstr);
    printf("-----------------------------\r\n");
}
extern "C" void __attribute__((visibility("default"))) SampleFunc03(int a, char *pstr)
{
    printf("--<SampleDll:SampleFunc03>--\r\n");
    printf("[%d] %s\r\n", a, pstr);
    sprintf(pstr, u8"C++ DLL側から文字列を返す場合は、StringBuilderクラスを使用する");
    printf("------------------------\r\n");
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 文字列のマーシャリング (2) ====
==== Windows ====
C++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
Windows向けC++ DLLの作成方法は[[ライブラリの基礎 - DLLの作成(C/C++/MFC)|ライブラリの基礎 - DLLの作成(C/C++/MFC)]]を参照する。<br>
<br>
<br>
下記にもC++ DLLを記述する。<br>
下記に、C++ DLLを記述する。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // SampleDLL.h
  // SampleDLL.h
799行目: 899行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== Linux / Windows ====
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
<br>
<br>
819行目: 920行目:
       /// <param name="a">4 バイト符号付き整数を指定します。</param>
       /// <param name="a">4 バイト符号付き整数を指定します。</param>
       /// <returns>倍精度浮動小数を返します。</returns>
       /// <returns>倍精度浮動小数を返します。</returns>
       [DllImport("SampleDLL.dll")]
       [DllImport("SampleDLL.dll")] // Windows
      [DllImport("SampleLib.so")]  // Linux
       private static extern double SampleFunc01(int a);
       private static extern double SampleFunc01(int a);
   
   
       [DllImport("SampleDLL.dll", CharSet = CharSet.Unicode)]
       [DllImport("SampleDLL.dll", CharSet = CharSet.Unicode)] // Windows
      [DllImport("SampleLib.so", CharSet = CharSet.Auto)]      // Linux
       // C++ DLL側の文字コードがUnicodeの場合は"CharSet = CharSet.Unicode"と明示的に指定する
       // C++ DLL側の文字コードがUnicodeの場合は"CharSet = CharSet.Unicode"と明示的に指定する
       private static extern void SampleFunc02(int a, string str);
       private static extern void SampleFunc02(int a, string str);
   
   
       [DllImport("SampleDLL.dll", CharSet = CharSet.Unicode)]
       [DllImport("SampleDLL.dll", CharSet = CharSet.Unicode)] // Windows
      [DllImport("SampleLib.so", CharSet = CharSet.Auto)]      // Linux
       // C++ DLL側の文字コードがUnicodeの場合は"CharSet = CharSet.Unicode"と明示的に指定する
       // C++ DLL側の文字コードがUnicodeの場合は"CharSet = CharSet.Unicode"と明示的に指定する
       private static extern void SampleFunc03(int a, StringBuilder str);
       private static extern void SampleFunc03(int a, StringBuilder str);
849行目: 953行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br><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>
1,088行目: 1,192行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
== 関数ポインタのマーシャリング ==
C# EXEからC++ DLLへコールバック関数を渡す。<br>
<br>
ただし、<code>Func</code>型、<code>Action</code>型、構造体内にある<code>char</code>型の配列のようなNon-Bittable型(非Blittable型)が含まれている場合、以下の例外が発生する。<br>
このような型の場合は、属性を用いたマーシャルの変換は不可能である。<br>
Non-blittable generic types cannot be marshaled.
<br>
<br>
 
==== Linux ====
==== 関数ポインタのマーシャリング ====
Linux向けのC++ライブラリを記述する。<br>
このセクションでは、C# EXEからC++ DLLへコールバック関数を渡す方法を記載する。<br>
<syntaxhighlight lang="c++">
// SampleLib.cpp
#include <cstdio>
#include <cstring>
using UnManagedCallback = bool (*)(int);
int __stdcall SampleCallback(UnManagedCallback CallbackFunc, int lPalam)
{
    int iRet = 0;
 
    bool bRet = CallbackFunc(lPalam);
    if(bRet)
    {
      iRet = 1;
    }
    else
    {
      iRet = -1;
    }
    return iRet;
}
</syntaxhighlight>
<br>
<br>
まず、以下にC++ DLLを記述する。<br>
==== Windows ====
  <source lang="c++">
Windows向けのC++ DLLを記述する。<br>
  <syntaxhighlight lang="c++">
  // SampleDLL.h
  // SampleDLL.h
   
   
1,100行目: 1,237行目:


  int __stdcall SampleCallback(int handle, int lPalam);
  int __stdcall SampleCallback(int handle, int lPalam);
  </source>
  </syntaxhighlight>
<br>
<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  // SampleDll.cpp
  // SampleDll.cpp
   
   
1,127行目: 1,264行目:
     return iRet;
     return iRet;
  }
  }
  </source>
  </syntaxhighlight>
<br>
<br>
  <source lang="c++">
  <syntaxhighlight lang="c++">
  // モジュール定義ファイル
  // モジュール定義ファイル
  // SampleDll.def
  // SampleDll.def
1,138行目: 1,275行目:
           ; 公開する関数名をリストアップ
           ; 公開する関数名をリストアップ
           SampleCallback  @1
           SampleCallback  @1
  </source>
  </syntaxhighlight>
<br>
<br>
==== Linux / Windows ====
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
次に、C# EXEからC++ DLLを呼び出す方法を記述する。<br>
<br>
<br>
1,145行目: 1,283行目:
以下の例では、ManagedCallBackというデリゲートを宣言している。<br>
以下の例では、ManagedCallBackというデリゲートを宣言している。<br>
C++ DLLのSampleCallBack関数にデリゲートを引数として渡すことで、既知のコールバック形式に自動的に変換される。<br>
C++ DLLのSampleCallBack関数にデリゲートを引数として渡すことで、既知のコールバック形式に自動的に変換される。<br>
  <source lang="c#">
  <syntaxhighlight lang="c#">
  using System;
  using System;
  using System.Runtime.InteropServices;
  using System.Runtime.InteropServices;
1,155行目: 1,293行目:
     class Program
     class Program
     {
     {
         [DllImport("SampleDLL.dll")]
         [DllImport("SampleDLL.dll")] // Windows
        [DllImport("SampleLib.so")]  // Linux
         private static extern int SampleCallback(ManagedCallBack CallBack, int lPalam);
         private static extern int SampleCallback(ManagedCallBack CallBack, int lPalam);


1,176行目: 1,315行目:
     }
     }
  }
  }
  </source>
  </syntaxhighlight>
<br><br>


== トラブル対処 ==
== トラブル対処 ==