3

monotouch を使用してサードパーティのバーコード スキャン ライブラリにバインドしようとしています。ライブラリ ヘッダー ファイルで定義されている次の方法を除いて、これまでのところすべて正常に動作しています。

/**
 * Main scan function. Invokes all activated decoders by priority.
 * For successful scan, allocates pp_data buffer and pass it to user.
 * User should deallocate *pp_data pointer when no more needed.
 *
 * @param[in]   pp_image                Byte array representing grayscale value of image pixels.
 *                                      Array shold be stored in row after row fashion, starting with top row.
 * @param[in]   lenX                    X axis size (width) of image.
 * @param[in]   lenY                    Y axis size (length) of image.
 * @param[out]  pp_data                 On successful decode, library allocates new byte array where it stores decoded
 *                                      string result. Pointer to string is passed here. User application is responsible
 *                                      for deallocating this buffer after use.
 *
 * @retval      >0                      Result string length for successful decode
 * @retval      MWB_RT_BAD_PARAM        Null pointer or out of range parameters
 * @retval      MWB_RT_NOT_SUPPORTED    Unsupported decoder found in execution list - library error
 */
extern int MWB_scanGrayscaleImage(uint8_t *  pp_image,  int lenX,  int lenY, uint8_t **pp_data);

C のデータ構造を直接扱ってからしばらく経ちましたが、 と をマップする方法がよくわかりませuint8_t * pp_imageuint8_t **pp_data

最初のパラメーターは、ピクセル バッファーからのグレースケール イメージを処理します。から画像バッファを取得していCMSampleBufferます。輝度が変換されたバイト配列、バイト配列のメモリ アドレスが必要ですか、それとも十分に渡さpixelBuffer.GetBaseAddress(0)れますか?IntPtr

最後のパラメーターはunsigned char *pResult=NULL;、objective-C デモのように初期化されるポインターに渡され、有効なスキャンが見つかったときにデータが入力されます。繰り返しますが、C# では初期化されていない/null バイト配列を渡すことができないため、これを初期化して渡す方法がわかりません。

IntPtr現在、私のバインディング ライブラリ コードは次のとおりです (ただし、 を使用して、ref を渡し、unsafe モードで直接アドレスを渡すことも試しました)。

[DllImport ("__Internal")]
extern static int MWB_scanGrayscaleImage (byte[] pp_image, int lenX, int lenY, out byte[] pp_data);
public static int ScanGrayscaleImage (byte[] pp_image, int lenX, int lenY, out byte[] pp_data)
{
    int result = MWB_scanGrayscaleImage(pp_image, lenX, lenY, out pp_data);
    return result;
}

これまでに試したすべての結果の値は、「スキャンに失敗しました」にマップされる -1 で返され続けます。これを理解するための助けをいただければ幸いです。

4

2 に答える 2

1

ライブラリはマネージ バイトを割り当てることができないため、uint8_t** を IntPtr としてバインドすることをお勧めします []

おそらく次のようなものです:

[DllImport ("__Internal")]
extern static int MWB_scanGrayscaleImage (byte[] pp_image, int lenX, int lenY, out IntPtr pp_data);
public static int ScanGrayscaleImage (byte[] image, int lenX, int lenY, out byte[] data)
{
    IntPtr pp_data;

    int result = MWB_scanGrayscaleImage (image, lenX, lenY, out pp_data);
    if (result > 0) {
        data = new byte[result];
        Marshal.Copy (pp_data, data, 0, result);
        Marshal.FreeHGlobal (pp_data); // I think this is what you want...
    } else {
        data = null;
    }

    return result;
}
于 2012-11-20T21:33:52.760 に答える
1

最初のパラメータは、輝度値を保持するバイト配列のメモリ アドレスですが、配列をパラメータとして渡す必要があります。

最後のパラメーターは、出力文字列への参照が格納される (有効な) メモリ位置を参照する必要があります。

次のようなことを試しましたか?

[DllImport ("__Internal")]
extern static int MWB_scanGrayscaleImage (byte[] pp_image, int lenX, int lenY, out byte[] pp_data);
public static int ScanGrayscaleImage (byte[] pp_image, int lenX, int lenY, out byte[] pp_data)
{
    int result;

    fixed (byte** pp_data_ptr = &pp_data) {
        result = MWB_scanGrayscaleImage(pp_image, lenX, lenY, pp_data_ptr);
    }

    return result;
}
于 2012-11-17T16:15:47.753 に答える