首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Rococoa访问位置的无效内存

使用Rococoa访问位置的无效内存
EN

Stack Overflow用户
提问于 2009-10-31 18:17:09
回答 2查看 1.1K关注 0票数 1

我一直在尝试使用rococoa (java到osx可可api库)编写一个简单的屏幕截图应用程序,并设法实现实际的截图,然后将其保存到一个文件中。不幸的是,偶尔应用程序会失败,因为“无效的内存访问位置.”。错误。我假设这是由于垃圾收集,因为我没有保持一个引用活着。导致崩溃的行是: int[] data = pointer.getIntArray(0,bytesPerPlane / 4);

我真的没有用目标C编码任何东西,只是从罗可可开始,所以我发现自己只是困惑于这个。我已经复制了下面的相关代码,并将非常感谢您的任何帮助!

代码语言:javascript
复制
public interface QuartzLibrary extends Library {

    QuartzLibrary INSTANCE = (QuartzLibrary) Native.loadLibrary("Quartz", QuartzLibrary.class);

    class CGPoint extends Structure {
        public double x;
        public double y;
    }

    class CGSize extends Structure {
        public double width;
        public double height;
    }

    class CGRect extends Structure implements Structure.ByValue {
        public static class CGRectByValue extends CGRect { }

        public CGPoint origin;
        public CGSize size;
    }

    int kCGWindowListOptionIncludingWindow = (1 << 3);
    int kCGWindowImageBoundsIgnoreFraming = (1 << 0);

    ID CGWindowListCreateImage(CGRect screenBounds, int windowOption, int windowId, int imageOption);
}

public interface NSBitmapImageRep extends NSObject {

    public static final _Class CLASS = Rococoa.createClass("NSBitmapImageRep", _Class.class);

    public interface _Class extends NSClass {
        NSBitmapImageRep alloc();
    }

    NSBitmapImageRep initWithCGImage(ID imageRef);
    com.sun.jna.Pointer bitmapData();
    NSSize size();
}

public class Screenshot {

    public static void getScreenshot(int windowId) throws IOException {
        QuartzLibrary.CGRect bounds = new QuartzLibrary.CGRect.CGRectByValue();
        bounds.origin = new QuartzLibrary.CGPoint();
        bounds.origin.x = 0;
        bounds.origin.y = 0;
        bounds.size = new QuartzLibrary.CGSize();
        bounds.size.width = 0;
        bounds.size.height = 0;
        ID imageRef = QuartzLibrary.INSTANCE.CGWindowListCreateImage(bounds, QuartzLibrary.kCGWindowListOptionIncludingWindow, windowId, QuartzLibrary.kCGWindowImageBoundsIgnoreFraming);

        NSBitmapImageRep imageRep = NSBitmapImageRep.CLASS.alloc();
        imageRep = imageRep.initWithCGImage(imageRef);
        NSSize size = imageRep.size();
        com.sun.jna.Pointer pointer = imageRep.bitmapData();

        int width = size.width.intValue();
        int height = size.height.intValue();

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        // The crash always happens when calling 'getIntArray' in the next line.
        int[] data = pointer.getIntArray(0, bytesPerPlane / 4);
        int idx = 0;
        for(int y = 0; y < height; y++)
            for(int x = 0; x < width; x++)
                image.setRGB(x, y, data[idx++]);

        ImageIO.write(image, "png", new File("foo.png"));
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-11-06 20:45:21

发现问题了。

'imageRep‘的最后一个用法是行"com.sun.jna.Pointer指针= imageRep.bitmapData();“。在此之后,imageRep对于Java垃圾收集器来说是公平的。如果它在我们使用“指针”之前命中,它所指向的支持缓冲区可能/将被释放,导致坏的事情发生。要解决这个问题,为imageRep添加一组额外的retain/retain就可以完成这项工作,或者将对它的任何引用添加到方法的末尾。

票数 2
EN

Stack Overflow用户

发布于 2009-10-31 23:48:34

可能是相关的,可能不是: NSBitmapImageRep是从NSImageRep下降的,而不是直接从NSObject下来的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1655145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档