我正在将存储为32位RGBA颜色数组的图像从C#传递到以C / C ++编写并打包在共享库中的Android原生插件。我的尝试是将颜色分解为扩展的字节数组,并将其传递给具有JNI jbooleanArray参数的本机函数,因为JNI typedef的未签名char为jboolean。但是,数据没有正确地跨越非托管边界:当我调用 GetBooleanArrayElements 时,我得到一个SEGFAULT。同样,在同一函数中作为jint参数传递的int图像高度也将变为负数,这并不是最初的结果。我的猜测是存在一些内存对齐/填充问题,使一切无法正常进行。
这是C库函数:
JNIEXPORT void JNICALL Detect(JNIEnv* env, jobject jobj, jbooleanArray rawImagePixelsUnraveled, jint imageWidth, jint imageHeight, jint maxDetectedShapes, jintArray outDetectedShapesCountSingleArray, jintArray outPointsPerShapeArray)
{
//assert(imageHeight >= 0);
jboolean isRawImagePixelsUnraveledCopy;
jboolean* rawImagePixelsUnraveledArray = env->GetBooleanArrayElements(rawImagePixelsUnraveled, &isRawImagePixelsUnraveledCopy);
...
}
这是相关的调用C#代码:
byte[] rawImagePixelsUnraveled = OpenCVInterop.Color32ArrayUnraveled(rawImagePixels);
IntPtr unmanagedArray = Marshal.AllocHGlobal(rawImagePixelsUnraveled.Length);
Marshal.Copy(rawImagePixelsUnraveled, 0, unmanagedArray, rawImagePixelsUnraveled.Length);
OpenCVInterop.Detect(unmanagedArray, phoneCameraDisplay.RenderingCameraTexture.width, phoneCameraDisplay.RenderingCameraTexture.height, _maxShapeDetectCount, ref _detectedShapesCount, _pointsPerShape);
Marshal.FreeHGlobal(unmanagedArray);
internal static class OpenCVInterop
{
static internal byte[] Color32ArrayUnraveled(Color32[] color32Array)
{
byte[] unraveledColor32Array = new byte[color32Array.Length * 4];
for(int i = 0; i < color32Array.Length; ++i)
{
unraveledColor32Array[4 * i] = color32Array[i].r;
unraveledColor32Array[4 * i + 1] = color32Array[i].g;
unraveledColor32Array[4 * i + 2] = color32Array[i].b;
unraveledColor32Array[4 * i + 3] = color32Array[i].a;
}
return unraveledColor32Array;
}
[DllImport("native-lib")]
internal static extern void Detect(IntPtr/*byte[]*/ rawImagePixels, int imageWidth, int imageHeight, int maxOutShapesCount, ref int outDetectedShapesCount, int[] outPointsPerShape);
}
我尝试发送字节数组本身并将其复制到IntPtr都没有成功。如何将字节数组从C#正确发送到C-land?谢谢。