Unity アプリのコード書いてた頃、iOS API や Android NDK を触る可能性があって調べた知識を供養します。
確かこんな感じだった気がする
詳しくは Csharp marshaling などで検索
blittable 型早見表
| C# | C(++) | Win32API |
|---|---|---|
byte |
unsigned char |
BYTE |
sbyte |
signed char |
INT8 |
short |
int16_t1
|
INT16 |
ushort |
uint16_t1
|
WORD |
int |
int32_t1
|
INT32 |
uint |
uint32_t1
|
DWORD |
long |
int64_t1
|
INT64 |
ulong |
uint64_t1
|
QWORD |
nint |
intptr_t1ポインター |
INT_PTRLONG_PTRハンドル |
nuint |
uintptr_t1ポインター |
UINT_PTRULONG_PTRハンドル |
float |
float32_t3
|
FLOAT |
double |
float64_t3
|
(なし?) |
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日閲覧)