最終更新日 2022-03-24

IntPtr型

概要

IntPtr型

これは「ポインタ」や「(実態がポインタである)ハンドル」を指し示すことに一番利用されます。
Windows APIには、「ハンドル」などもよく出てきますが、それらも実態はポインタですので、
「IntPtr」はDllImport周りでは頻発することとなります。

しかし、そういったポイント系の使い方だけではなく、
「x86なら32bit」「x64なら64bit」である、という性質を利用して「OSのビット数に応じて変化する数値」として
IntPtr型が利用するシーンもあります。

又、C#9.0以降は、この「数値としての利用」にフォーカスを当てて、「nint」という型が導入されました。
コンパイル時には、「nint」は「IntPtr」へと変換されますが、C#で記述する上では、
数値計算などにおいて、キャストが不要となり、扱いやすくなっています。

IntPtr型

  • C++側のソース

    Dll1.dllとしてコンパイル
    #include <windows.h>
    #include <cstddef>
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <string>
    
    using namespace std;
    
    #define DLLEXPORT __declspec(dllexport) WINAPI
    
    
    
    // intptr_tの受け渡し
    extern "C" intptr_t DLLEXPORT dllIntPtr(const intptr_t pIntPtrValue) {
    	return pIntPtrValue + 300;
    }
    
  • C#側のソース

    test1.cs
    using System;
    using System.Runtime.InteropServices;
    
    namespace test1
    {
        internal class Program
        {
            [DllImport("Dll1.dll")]
            static extern IntPtr dllIntPtr(IntPtr value);
    
            static void Main(string[] args)
            {
                // x86なら 32bit、x64なら64bitの数値型
                IntPtr value = (IntPtr)10000;
                IntPtr ret = dllIntPtr(value);
                Console.WriteLine(ret);
    
                // C# 9.0 なら nint 型があるので
                // nint value = 1000;
                // nint ret = dllIntPtr(value);
                // Console.WriteLine(ret);
                // とキャストなどしなくても書ける
    
                Console.ReadKey();
            }
        }
    }