结构

时间:2017-03-23 18:42:34

标签: c# pinvoke

我需要使用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(错误检查无效)。

0 个答案:

没有答案