文章にまだまとめていないもの。
== プラットフォーム呼び出し メモ
・共用体を表現しようとしてLayoutKind::ExplicitとFieldOffsetを用いるときは、charをSystem::Byteにマッピングする。System::Charにするとwchar_tで2バイト使っているので、StructureToPtrで割り当て先不足(HRESULT: 0x8007007A)が発生する。
・「EventWaitHandle」とkernel32の「DeviceIoControl」を組み合わせて使わなくても、ksproxy.axの「KsSynchronousDeviceControl」を呼び出ししても同じ結果を得られた。パフォーマンスはどうだろう??
・MSDNの「FindFile のサンプル」で示されているような構造体の平坦化はしない。StructLayoutを指定している構造体をネストする分にはマーシャリングはきちんとされる。
== VST Host メモ
・VSTiの呼び出し規約はcdecl
・VSTiをロードしたらVSTiのスレッドが生み出されている可能性がある為、effOpenしていなくても、effCloseを呼び出してからアンロードする(VSTi側の造りに依るとは思う)
・プラグインの中には「kVstMax~」の制限に従っていないものもあるので、受けるバッファは大きめで取っておかないといけない(とかどうしようもない)
・AEffectDispatcherProcの戻り値もプラグインによってバラバラなので、戻り値は参考にできない(成功値が0だったり1だったりいろいろ)
== あまり参考にしてはならないモノ
・ドライバにメモリブロックを参照させるときは、GlobalAllocで確保して、GlobalLockでスワップさせないようにしなければならない、、、とセオリーで考えていたけども、LocalAlloc(≒bittable型のarrayをpinで止めたモノ)でも動いてしまっている。
考えが16bit時代で止まってしまっているかしら。
しばらくLocalAllocで進めるが、どこかで問題が起きるかもしれないので注意しておく。
・waveOutOpenでコールバックをFUNCTIONにしていて、waveOutWriteからのWOM_DONEがコールバックされた時は、コールバック関数中にwaveOutUnprepareHeaderを呼び出しても大丈夫だが、waveOutResetからのWOM_DONEがコールバックされた時にwaveOutUnprepareHeaderを呼び出すとデッドロックする。
ドライバに依るかもしれないが、そもそもMSDNでも呼び出し禁止になっているので、waveOutUnprepareHeaderはいずれの場合もコールバック関数の外で呼び出さないとダメ。
・構造体のtypedefを継承で置き換えると、System::Runtime::InteropServices::Marshal::SizeOfの返り値が1バイト増える。
== System::Tupleをジェネリック関数の戻り値に使うと、C2440エラーが出る場合がある。
あまりやらないコードなのかもしれないが、必要になったので定義したところ、下記はコンパイルエラーになってしまう。
{{{ code cpp
ref class A {
generic<typename OUT>
System::Tuple<OUT>^ method1(int b) {
OUT d;
return gcnew System::Tuple<OUT>(d); // error C2440: 'return' : 'System::Tuple<T1> ^' から 'System::Tuple<T1> ^' に変換できません。
}
generic<typename OUT>
System::Tuple<OUT>^ method2(int b, int c) {
OUT d;
return gcnew System::Tuple<OUT>(d); // error C2440: 'return' : 'System::Tuple<T1> ^' から 'System::Tuple<T1> ^' に変換できません。
}
};
}}}
但し、ジェネリックメソッドを1つだけ定義している場合、
{{{ code cpp
ref class A {
generic<typename OUT>
System::Tuple<OUT>^ method1(int b) {
OUT d;
return gcnew System::Tuple<OUT>(d);
}
};
}}}
ジェネリックの型指定の数が異なる場合、
{{{ code cpp
ref class A {
generic<typename OUT>
System::Tuple<OUT>^ method1(int b) {
OUT d;
return gcnew System::Tuple<OUT>(d);
}
generic<typename IN, typename OUT>
System::Tuple<OUT>^ method2(IN b) {
OUT d;
return gcnew System::Tuple<OUT>(d);
}
};
}}}
ジェネリック関数ではなく、ジェネリッククラスとしている場合はコンパイルが通る。
{{{ code cpp
generic<typename OUT>
ref class A {
System::Tuple<OUT>^ method1(int b) {
OUT d;
return gcnew System::Tuple<OUT>(d);
}
System::Tuple<OUT>^ method2(int b, int c) {
OUT d;
return gcnew System::Tuple<OUT>(d);
}
};
}}}
また、適当なTupleを自前で用意した場合も、コンパイルが通る。
{{{ code cpp
ref class A {
generic<typename OUT>
ref class Tuple {
public:
OUT t;
Tuple(OUT v): t(v) {};
};
generic<typename OUT>
Tuple<OUT>^ method1(int b) {
OUT d;
return gcnew Tuple<OUT>(d);
}
generic<typename OUT>
Tuple<OUT>^ method2(int b, int c) {
OUT d;
return gcnew Tuple<OUT>(d);
}
};
}}}