gpt4 book ai didi

java - Rococoa 位置的内存访问无效

转载 作者:行者123 更新时间:2023-11-30 05:15:18 24 4
gpt4 key购买 nike

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

我真的没有用 Objective C 编写过任何代码,只是从 rococoa 开始,所以我发现自己对此感到困惑。我已经复制了下面的相关代码,非常感谢任何帮助!

<小时/>
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"));
}
}

最佳答案

发现问题了。

‘imageRep’的最后一次使用上线了“com.sun.jna.Pointer 指针 = imageRep.bitmapData();”。此后,imageRep 对于 Java 垃圾收集器来说是公平的游戏。如果它击中在我们使用完“指针”之前,它指向的后备缓冲区可能/将会得到被释放,导致不好的事情发生。要修复此问题,请为 imageRep 添加一组额外的保留/释放即可完成此工作,或者将对其的任何引用添加到方法的末尾。

关于java - Rococoa 位置的内存访问无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1655145/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com