Unity アプリのコード書いてた頃、iOS API や Android NDK を触る可能性があって調べた知識を供養します。
確かこんな感じだった気がする
詳しくは Csharp marshaling などで検索
blittable 型早見表
C# | C(++) | Win32API |
---|---|---|
byte |
unsigned char |
BYTE |
sbyte |
signed char |
INT8 |
short |
int16_t 1
|
INT16 |
ushort |
uint16_t 1
|
WORD |
int |
int32_t 1
|
INT32 |
uint |
uint32_t 1
|
DWORD |
long |
int64_t 1
|
INT64 |
ulong |
uint64_t 1
|
QWORD |
nint |
intptr_t 1ポインター |
INT_PTR LONG_PTR ハンドル |
nuint |
uintptr_t 1ポインター |
UINT_PTR ULONG_PTR ハンドル |
float |
float32_t 3
|
FLOAT |
double |
float64_t 3
|
(なし?) |
ref T (プリミティブ blittable 型の参照渡し) |
T * |
T * |
T[] (プリミティブ blittable 型の1次元配列) |
T[] T *
|
T[] T *
|
この他、ある構造体のメンバー変数がすべて blittable な値型なら、その構造体もまた blittable です。
blittable じゃないけど知っておくと便利な型
これらの型はマーシャリングの負荷が小さいらしいです。
C# | C(++) | Win32API |
---|---|---|
[MarshalAs(UnmanagedType.LPWSTR)] string |
const char16_t * |
LPCWSTR |
[MarshalAs(UnmanagedType.LPWSTR)] System.Text.StringBuilder |
char16_t * |
LPWSTR |
[MarshalAs(UnmanagedType.Bool)] bool |
不明 (Widows 以外あてにならない) | BOOL |
[MarshalAs(UnmanagedType.I1)] bool |
Objective-C における BOOL
|
BOOLEAN |
blittableっぽいけど使うべきでない型
C言語の int
, long
具体的なサイズがほとんど定義されてない (仮にうまく動いても単なる偶然) ので、C言語側のコードで int
型を使うのは非推奨です。
long
は Windows ではビット長に関係なく 32bit ですが他のOSだとそうじゃなかったりするのであまりポータブルじゃないです。
C言語の float
, double
それぞれでサイズが同じでも表現規定が違うため、互換性が保証されていません。
- C#「IEEE 754 でよろ」
- C「具体的な内部表現は処理系依存」
C# の char
C# の char
は Win32API の WCHAR と同じなんじゃないかと思ったのですが、なんだか複雑な事情があるみたいで簡単にはマーシャリングできないようです。
実際に試したらうまくいかなかった記憶があるのですが……あれはいつの話だったかなぁ?
参考
- 「wchar_tは何ビット?ワイド文字の取扱いメモ」(https://qiita.com/everylittle/items/25d5f407f51f5e515d29) (2024年6月10日閲覧)