2005年05月07日
川俣晶の縁側ソフトウェア技術雑記total 53129 count

C++/CLIでmanagedなバイト配列をネイティブなバイト配列を処理する関数に渡す

Written By: 川俣 晶連絡先

 ネイティブなバイト配列を処理する関数があるとします。

 これに対して、managedなバイト配列を渡して処理させたいとします。

 パフォーマンスに影響するため、1バイトずつコピーする処理は避けたいと思います。

 以上の条件を実現したサンプルコードを書いてみました。

サンプルソース §

 Visual C++ Express 2005 Beta2で、managedコンソールアプリケーションのテンプレートでプロジェクト作成後に、以下のソースを入力します。

#include "stdafx.h"

#include <stdio.h>

using namespace System;

array<Byte>^ createByteArray()

{

    array<Byte>^ ar = gcnew array<Byte>(3);

    ar[0] = 1;

    ar[1] = 2;

    ar[2] = 3;

    return ar;

}

#pragma unmanaged

void dumpArray( Byte ar[], int length )

{

    for( int i=0; i<length; i++ )

    {

        printf("%d\n",ar[i]);

    }

}

#pragma managed

int main(array<System::String ^> ^args)

{

    array<Byte>^ ar = createByteArray();

    pin_ptr<Byte> pNative = &ar[0];

    dumpArray(pNative,ar->Length);

    return 0;

}

実行結果 §

1

2

3

解説 §

 managedな配列は"array<型>"の書式で型を指定します。あまりにC++らしくないので、うっかり忘れると思い出せない罠があります。(うっかりはまった!)

 データ型は、blittable型と、非blittable型に分類できます。blittable型は、managedとunmanaged(ネイティブ)で内部表現が同じもの。非blittable型は同じにならないものです。blittable型には整数などがあり(Byte型を含む)、これらはマーシャリングに悩むことなくmanagedとunmanagedの世界を往復できます。

 blittable型の配列も、blittable型になります。

 よって、Byte型の配列もblittable型になります。

 つまり、managedなByte配列を、そのままネイティブなByte配列を処理する関数に渡しても正常に動作します。

 問題は2つ。いかにしてmanagedなByte配列を指し示すネイティブなポインタを手に入れるか。そして、ネイティブコードからアクセス中の安全性をいかにして確保するか (ガベージコレクタに移動させられたくない) です。

 前者は、配列の最初の要素のアドレスを取得するコードを書けばOKです。ここでは、"&ar[0]"というコードを書いています。これは単に"ar"と書いては不可です。managedコード側の都合としては、"ar"とは配列"オブジェクト"であって、Byte型の値の入れ物とは性質が違うものであると判断されるためだと推測します。

 後者は、pin_ptrによって実現します。pin_ptrは、cli名前空間に属する言語要素で、ガベージコレクタに対して固定されたポインタを宣言します。つまり、ここでは"pin_ptr<Byte>"によって、Byte型の固定ポインタとして宣言されたことで、変数arに対応する配列オブジェクトは固定されます。その結果、ガベージコレクタが発動したとしても、配列オブジェクトは回収されたり移動されることが無くなります。その結果、ネイティブコード関数は、思う存分、心ゆくまで、配列が常に固定アドレスに存在することを前提に、あらゆるトリックを使って処理を行うことができます。

 このことは、あらゆるトリックを使うべきだという意味ではありません。既にあらゆるトリックを使って書いてしまったネイティブコード関数を、managedコードから利用できることを意味するわけです。

感想 §

 やりたい放題。

 危ないコードもバッチリOK。

 それは、新規に記述するコードでは全くお勧めではありませんが、既に書かれているコードの活用という観点からは心強い特徴です。

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2005年
05月
08日
C++/CLIでネイティブな文字列とmanagedな文字列を相互変換する「試行」その2
3days 0 count
total 19104 count
【技術雑記】の前のコンテンツ
2005年
05月
07日
おっと、見落としていた! C++/CLIはfor eachまで揃っている!!
3days 0 count
total 20395 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20050507224044
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.