2012-11-17 40 views
3

我试图绑定到使用monotouch的第三方条码扫描库 - 除了以下方法之外,一切工作都很顺利库头文件:在Monotouch中绑定到第三方库 - 映射uint8_t *和uint8_t **

/** 
* 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就足够了?

最后一个参数被传入一个指针,该指针在objective-C演示中被初始化为unsigned char *pResult=NULL;,然后在找到有效扫描时被填充数据。再次,我不确定如何初始化并传入,因为您无法在C#中传入未初始化/空字节数组。

我绑定库的代码是目前如下(虽然我也用IntPtr尝试,由参传递,并通过不安全的方式直接地址):

[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,映射到“扫描失败”。任何帮助搞清楚这将不胜感激。

回答

1

我建议结合uint8_t **作为一个IntPtr,因为图书馆将无法分配管理的byte []

也许是这样的:

[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; 
} 
+0

完美运行 - 谢谢! – JohnSvo

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; 
} 
+0

感谢帮助,我觉得我至少在球场上,但我在这条线上得到一个错误: 'fixed(byte ** pp_data_ptr =&pp_data){' _Cannot取地址,得到大小的,或宣布一个宝inter到托管类型'byte []'_ – JohnSvo