バイト配列のマーシャリングについて – プログラミング – Home

バイト配列のマーシャリングについて
 
通知
すべてクリア

[解決済] バイト配列のマーシャリングについて

固定ページ 1 / 2

human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

アンマネージ
unsigned char aaa[8];

マネージ
array<unsigned char>^ bbb;

上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
ーシャリングをしたところビルドでエラーとなりました。この記述方法
が正しいかどうかご教授お願いします。

マーシャリング
Marshal::Copy(static_cast<IntPtr>(aaa), bbb, 0, bbb->Length());

エラー内容
error C2064: 0引数を取り込む関数には評価されません。

宜しくお願いします。


引用未解決
トピックタグ
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

失礼しました。

>>上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
>>ーシャリングをしたところビルドでエラーとなりました。この記述方法
>>が正しいかどうかご教授お願いします。

マネージ配列bbbからアンマネージ配列aaaの間違いです


返信引用
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

たびたびすみません・・・。

>>上記の配列がありこれをマネージ配列aaaからアンマネージ配列bbbへマ
>>ーシャリングをしたところビルドでエラーとなりました。この記述方法
>>が正しいかどうかご教授お願いします。

アンマネージ配列aaaからマネージ配列bbbへのマーシャリングです。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

引数の数が間違っていますね。
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);


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

あー逆か。

逆でもどうにでもなりそう。

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);


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

ちなみに
>error C2064: 0引数を取り込む関数には評価されません。

>bbb->Length()
に対してのエラーです。
プロパティなので () は不要です。


返信引用
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

>>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はよろしくない??


返信引用
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

>>ちなみに
>>>error C2064: 0引数を取り込む関数には評価されません。

>>>bbb->Length()
>>に対してのエラーです。
>>プロパティなので () は不要です。

ありがとうございます。初歩的なところでハマってました。
このエラーの件については()を外して解決しました。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

というかIntPtrとvoid*は型が全く違うわけなの(単純なキャストでうまくいくのか)で
IntPtrにvoid*を引数にするコンストラクタがある以上そちらを使うべきかと。
(IntPtrの実装がどうなっているかわからないし。)


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>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


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>たぶん operator の方が呼ばれて結果は同じということではないかと。
メソッドのツリーのほうにあったの気付かなかった。。。(メンバだけみただけ)

でも、個人的には逆の場合はIntPtr::ToPointerを使うわけなんでコンストラクタを使う
やり方のほうが好きですね。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>逆の場合はIntPtr::ToPointerを使うわけなんで
ではなかったでした。void*にならoperatorでキャストできますね。
まあ、unsigend char*に一気にキャストできるわけではないですが。
(ToPointerを使ったほうが普通っぽい。)


返信引用
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

>>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;

としています。考えられる原因は何でしょうか?


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

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);


返信引用
human
 human
(@human)
ゲスト
結合: 15年前
投稿: 26
Topic starter  

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の実態を生成出来るのでしょうか?あまりテク
ニックがなくて申し訳ございません。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました