我需要使用C接口连接到第三方应用程序,但是到目前为止我尝试的所有内容都会在使用ImageArray.images
字段时崩溃应用程序。
其中一个方法需要一个声明为:
的结构typedef struct {
int size;
Image **images;
} ImageArray;
Image
类型是一个简单的结构,只有int
个字段(如宽度和高度):
typedef struct {
int width;
int height;
} Image;
可以首先访问derefencing数组元素的图像,而不是取消引用Image
结构。例如:
ImageArray imageArray = ... // initialize it somehow.
imageArray[0]->width
我尝试从C#调用但未成功的函数声明为:
int Segment(Image *image, ImageArray **images);
到目前为止,我已声明以下结构和方法与本机库接口:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct Image
{
public int Width;
public int Height;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal unsafe struct ImageArray
{
public Int32 Size;
public IntPtr Images;
}
public static extern int Segment([In] ref Image image, [Out] out IntPtr images);
另外,我已经实现了以下包装器,它会触发错误:
IntPtr imagesArrayPtr;
Segment(ref nImage, out imagesArrayPtr));
var imageArray = (ImageArray)Marshal.PtrToStructure(imagesArrayPtr, typeof(ImageArray));
var sz = imageArray.Size;
var ptr = imageArray.Images;
var images = new Image[imageArray.Size];
for (var i = 0; i < imageArray.Size; i++)
{
images[i] = (Image)Marshal.PtrToStructure(ptr, typeof(Image));
ptr = new IntPtr(ptr.ToInt32() + Marshal.SizeOf(typeof(IntPtr)));
}
我删除了错误检查以减少代码大小。
这个例子我在查看其他堆栈溢出问题时出现了。
如何正确实施此次通话?
更新:从C / C ++调用Segment
(错误检查无效):
Image *image;
ImageLoadFromFile("file.png", &image);
ImageArray *imageArray;
Segment(image, &imageArray);
for ( int i = 0; i < imageArray->size; i++ ) {
const Image *img = imageArray[i];
printf("width=%d height=%d\n", img->width, img->height);
}
函数ImageLoadFromFile
在第二个参数的第一个参数处加载指定的图像,如果成功则返回true
(错误检查无效)。