2009-10-31 36 views
1

我一直在嘗試使用rococoa(java到osx cocoa api庫)來編寫一個簡單的屏幕截圖應用程序,並儘可能實際採取屏幕截圖,然後將其保存到文件。不幸的是,有一段時間,應用程序失敗,出現「無效的內存訪問...」錯誤。我假設這是由於垃圾收集的原因,因爲我沒有保持參考文件的存在。導致崩潰的行是: 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")); 
    } 
} 

回答

2

發現問題。

'imageRep'的最後一次使用是在行 「com.sun.jna.Pointer pointer = imageRep.bitmapData();」。 之後,imageRep是Java垃圾回收器的公平遊戲。如果在我們完成使用'指針'之前碰到 ,它指向的後備緩衝區可能會被釋放,導致不好的事情發生。 要修復它,爲imageRep添加一組額外的保留/版本可以完成這項工作,或者在該方法的末尾添加任何對它的引用。

0

可能相關的,可能不是:NSBitmapImageRep從NSImageRep下降,而不是直接從NSObject的。

相關問題