アンマネージ
unsigned char aaa[8];
マネージ
array<unsigned char>^ bbb;
上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
ーシャリングをしたところビルドでエラーとなりました。この記述方法
が正しいかどうかご教授お願いします。
マーシャリング
Marshal::Copy(static_cast<IntPtr>(aaa), bbb, 0, bbb->Length());
エラー内容
error C2064: 0引数を取り込む関数には評価されません。
宜しくお願いします。
失礼しました。
>>上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
>>ーシャリングをしたところビルドでエラーとなりました。この記述方法
>>が正しいかどうかご教授お願いします。
マネージ配列bbbからアンマネージ配列aaaの間違いです
たびたびすみません・・・。
>>上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
>>ーシャリングをしたところビルドでエラーとなりました。この記述方法
>>が正しいかどうかご教授お願いします。
アンマネージ配列aaaからマネージ配列bbbへのマーシャリングです。
引数の数が間違っていますね。
Marshal::CopyはIntPtrを引数に取るので、配列の先頭要素へのポインタをIntPtrにして
から渡します。
unsigned char aaa[8];
array<unsigned char>^ bbb = {1, 2, 3, 4, 5, 6, 7, 8};
System::Runtime::InteropServices::Marshal::Copy(bbb, 0, IntPtr(&aaa[0]),
bbb->Length);
もっとも、C++/CLIなのでmemcpyでもよいかも。
pin_ptr<unsigned char> p = &bbb[0];
memcpy(aaa, p, bbb->Length);
あー逆か。
逆でもどうにでもなりそう。
unsigned char aaa[8] = {1, 2, 3, 4, 5, 6, 7, 8};
array<unsigned char>^ bbb = gcnew array<unsigned char>(8);
System::Runtime::InteropServices::Marshal::Copy(IntPtr(&aaa[0]), bbb, 0, 8);
memcpyなら
pin_ptr<unsigned char> p = &bbb[0];
memcpy(p, aaa , bbb->Length);
ちなみに
>error C2064: 0引数を取り込む関数には評価されません。
は
>bbb->Length()
に対してのエラーです。
プロパティなので () は不要です。
>>Blueさん
大変分かりやすい説明とサンプルコードありがとうございます。
1点確認ですが
>>引数の数が間違っていますね。
>>Marshal::CopyはIntPtrを引数に取るので、配列の先頭要素へのポインタをIntPtrにし
>>てから渡します。
>>unsigned char aaa[8];
>>array<unsigned char>^ bbb = {1, 2, 3, 4, 5, 6, 7, 8};
>>System::Runtime::InteropServices::Marshal::Copy(bbb, 0, IntPtr(&aaa[0]),
>>bbb->Length);
上記はマネージからアンマネージのマーシャリングですよね。
System::Runtime::InteropServices::Marshal::Copy(bbb, 0,
static_cast<System::IntPtr>(aaa), bbb->Length);
この書き方でも値がコピーされているように見えるのですがこの記述では駄目なのでしょ
うか?そもそもマーシャリングでstatic_castはよろしくない??
>>ちなみに
>>>error C2064: 0引数を取り込む関数には評価されません。
は
>>>bbb->Length()
>>に対してのエラーです。
>>プロパティなので () は不要です。
ありがとうございます。初歩的なところでハマってました。
このエラーの件については()を外して解決しました。
というかIntPtrとvoid*は型が全く違うわけなの(単純なキャストでうまくいくのか)で
IntPtrにvoid*を引数にするコンストラクタがある以上そちらを使うべきかと。
(IntPtrの実装がどうなっているかわからないし。)
>System::Runtime::InteropServices::Marshal::Copy(bbb, 0,
>static_cast<System::IntPtr>(aaa), bbb->Length);
>
>この書き方でも値がコピーされているように見えるのですがこの記述では駄目なのでしょ
>うか?そもそもマーシャリングでstatic_castはよろしくない??
たぶん operator の方が呼ばれて結果は同じということではないかと。
http://msdn.microsoft.com/ja-jp/library/e4y9h1at(VS.80).aspx
>たぶん operator の方が呼ばれて結果は同じということではないかと。
メソッドのツリーのほうにあったの気付かなかった。。。(メンバだけみただけ)
でも、個人的には逆の場合はIntPtr::ToPointerを使うわけなんでコンストラクタを使う
やり方のほうが好きですね。
>逆の場合はIntPtr::ToPointerを使うわけなんで
ではなかったでした。void*にならoperatorでキャストできますね。
まあ、unsigend char*に一気にキャストできるわけではないですが。
(ToPointerを使ったほうが普通っぽい。)
>>Blueさん
>>というかIntPtrとvoid*は型が全く違うわけなの(単純なキャストでうまくいくのか)で
>>IntPtrにvoid*を引数にするコンストラクタがある以上そちらを使うべきかと。
なるほど確かにおっしゃるとおりですね。
System::Runtime::InteropServices::Marshal::Copy(IntPtr(&aaa[0]), bbb, 0, 8);
試しに上記のコードでアンマネージからマネージへコピーしてみたところビルドは通るの
ですが
パラメータのbbbでNullReferenceException が発生しエラーとなりました。
bbbの配列は構造体のpublicなメンバで構造体の中で
[System::Runtime::InteropServices::MarshalAs(UnmanagedType::ByValArray,
SizeConst=8]
array<unsigned char>^ bbb;
としています。考えられる原因は何でしょうか?
bbbの実態を作成していないからではでは?
>unsigned char aaa[8] = {1, 2, 3, 4, 5, 6, 7, 8};
>>>array<unsigned char>^ bbb = gcnew array<unsigned char>(8);
>System::Runtime::InteropServices::Marshal::Copy(IntPtr(&aaa[0]), bbb, 0, 8);
Blueさんのご指摘通り実態を生成しないで直接構造体のメンバbbbを見に行っておりまし
た。この場合、一旦、array<unsigned char>^ ccc = gcnew array<unsigned char>(8);
で実態を生成して構造体のメンバbbbにコピーしなければいけないのでしょうか?cccを生
成しなくても直接構造体のメンバbbbの実態を生成出来ますでしょうか?
構造体の定義は以下です。
public value struct TEST
{
public:
[System::Runtime::InteropServices::MarshalAs(UnmanagedType::ByValArray,
SizeConst=8]
array<unsigned char>^ bbb;
}
マーシャリングをおこなう関数の先頭で
TEST test;
として
System::Runtime::InteropServices::Marshal::Copy(IntPtr(&aaa[0]), test.bbb, 0,
8);
とするとtest.bbbの実態が生成されていないためエラーとなる。
複数コードにならずに1行で直接test.bbbの実態を生成出来るのでしょうか?あまりテク
ニックがなくて申し訳ございません。