旧鯖時代の雑記です。新しいの。リンク切れに注意。
2007:
12345678910
2006:
123456789101112
2005:
123456789101112
2004:
456789101112
ドージンワーク#4, あねちっくセンセーション#2, ゆるめいつ#1。なんか4コマ買いすぎな気がします。
コメントはありません。
C#でネットワーク通信を行いたい場合ソケットはbyte[]を要求します。しかし構造体をbyte[]に変換する方法は特に用意されていません。unsafeをつけない場合Marshalクラスを用いてやればできますが、2重にメモリを確保しメモリコピーが2回起きるのでどうにも気持ち悪く感じます。そこでunsafeコードを使用すると下記のようなコードになります。
unsafe static byte[] ToByteArray(Struct v) {
byte[] ret = new byte[sizeof(Struct)];
byte* p = (byte *)&v;
for(int i = 0; i < ret.Length; i++)
ret[i] = p[i];
return ret;
}
unsafe static Hoge FromByteArray(byte[] v) {
if(v.Length != sizeof(Struct))
throw new ArithmeticException();
Struct ret = new Hoge();
byte* p = (byte *)&ret;
for(int i = 0; i < v.Length; i++)
p[i] = v[i];
return ret;
}
これは問題なくコンパイルがとおり意図した結果を返します。しかしどうせならStructの部分を任意の構造体Tに対して行いたくなってくるわけです。そこでジェネリックを使用して次のようなコードを書いてみました。
unsafe static byte[] ToByteArray<T>(T v) where T:struct {
byte[] ret = new byte[sizeof(T)];
byte* p = (byte *)&v;
for(int i = 0; i < ret.Length; i++)
ret[i] = p[i];
return ret;
}
unsafe static T FromByteArray<T>(byte[] v) where T:struct {
if(v.Length != sizeof(Hoge))
throw new ArithmeticException();
T ret = default(T);
byte* p = (byte *)&ret;
for(int i = 0; i < v.Length; i++)
p[i] = v[i];
return ret;
}
しかしこれはコンパイルが通りません。コンパイルエラーを見るにTが参照型と認識されているようで無理なようです。型制約が意味をなしてない気がしますがどうなんでしょう?どうしても任意の型に対して行いたい場合C++/CLIを使って次のようにすればいけるみたいです。
generic<typename T> where T: value class
static array<System::Byte> ^ToByteArray(T value) {
array<System::Byte> ^ret = gcnew array<System::Byte>(sizeof(T));
pin_ptr<T> pin = &value;
unsigned char* p = reinterpret_cast<unsigned char*>(pin);
for(int i=0; i<ret->Length; i++)
ret[i] = p[i];
return ret;
}
generic<typename T> where T: value class
static T FromByteArray(array<System::Byte> ^value) {
if(value->Length != sizeof(T))
throw gcnew System::ArgumentException();
T ret = gcnew T();
pin_ptr<T> pin = &ret;
unsigned char* p = reinterpret_cast<unsigned char*>(pin);
for(int i=0; i<value->Length; i++)
p[i] = value[i];
return ret;
}
コメントはありません。
駄目な理由がわかりました。C#では参照型をフィールドに含む構造体のポインタは取れないようです。だから不特定の構造体Tだとコンパイルエラーになるわけですね。
コメントはありません。
6年目ですよ。去年はぐだぐだ路線とか言ってますが、今年はさらに輪をかけてぐだぐだ。目標は色々とありますが、目下動いてるのが2本あるのでそれを何とかしないとサイトまではむりかなぁ。
コメントはありません。
Copyright(C)方位記号