2015-04-02 29 views
0

當我使用jna時,GlobalAlloc和GlobalLock都返回指針,但是我發現它們的表現都好像它們不相等。GlobalAlloc和GlobalLock之間在JNA中的返回值有什麼區別

例如,

在下面這種情況下,我發現TestStructure的實例 沒有我預期的正常狀態。

Kernel32 kernel32 = Native.loadLibrary("kernel32",Kernel32.class); 
Pointer pointer = kernel32.GlobalAlloc(ghnd, size); 
Pointer pointer2 = kernel32.GlobalLock(pointer); 
pointer2.write(0, testbyte, 0, dmSize); 
TestStructure structure = new TestStructure(pointer); 

但下面的情況正常工作。

Kernel32 kernel32 = Native.loadLibrary("kernel32",Kernel32.class); 
Pointer pointer = kernel32.GlobalAlloc(ghnd, size); 
Pointer pointer2 = kernel32.GlobalLock(pointer); 
pointer2.write(0, testbyte, 0, dmSize); 
TestStructure structure = new TestStructure(pointer2); 

爲什麼我必須使用pointer2實例來創建TestStructure。 我認爲指針和指針2應該指向相同的地方。

// add 2015.04.03

1是的,我正在使用Windows平臺。

2請參閱下面的TestStrucure。

public class TestStructure extends Structure { 

    public char[] dmDeviceName = new char[32]; 
    public WORD dmSpecVersion; 
    public WORD dmDriverVersion; 
    public WORD dmSize; 
    public WORD dmDriverExtra; 
    public DWORD dmFields; 
    public UnionField1 unionField1; 
    public short dmColor; 
    public short dmDuplex; 
    public short dmYResolution; 
    public short dmTTOption; 
    public short dmCollate; 
    public char[] dmFormname = new char[32]; 
    public WORD dmLogPixels; 
    public DWORD dmBitsPerpel; 
    public DWORD dmPelsWidth; 
    public DWORD dmPelsHeight; 
    public UnionField2 unionField2; 
    public DWORD dmDisplayFrequency; 

    public TestStructure(Pointer pointer) { 
    useMemory(pointer); 
    read(); 
    } 

    @Override 
    protected List getFieldOrder() { 
    return Arrays.asList(new String[] { "dmDeviceName", "dmSpecVersion", "dmDriverVersion", "dmSize", 
      "dmDriverExtra", "dmFields", "unionField1", "dmColor", "dmDuplex", "dmYResolution", "dmTTOption", 
      "dmCollate", "dmFormname", "dmLogPixels", "dmBitsPerpel", "dmPelsWidth", "dmPelsHeight", "unionField2", 
      "dmDisplayFrequency" }); 
    } 
}  
+0

什麼'TestStructure'的定義是什麼? – 2015-04-02 12:20:43

+0

爲什麼你需要管理你的JNA結構使用的內存? – technomage 2015-04-02 18:36:27

+0

我不需要管理內存,但是我使用第一個示例代碼面對此錯誤,並通過將其修復爲第二個示例來解決。所以我想明白爲什麼第一個例子是錯誤的,因爲它們看起來都與Java中的指針相同。我想知道,如果內存塊可能是jna中的指針,爲什麼不能將它們用作指針。 – 2015-04-03 01:32:40

回答

1

我假設您正在開發Windows平臺。 GlobalXx函數實際上是對舊的16位Windows的回憶。在(舊)時間,GlobalAlloc用於通過GlobalLock將轉換器的(16位)句柄返回到32位指針。

如果您要求使用GHND = 0x42作爲第一個參數的可移動內存塊,仍然可以表現出類似的行爲。如果您做GlobalAlloc返回一個(32位)句柄,必須將其轉換爲一個與GlobalLock真實指針。可以通過對GlobalLock - GlobalUnlock的不同調用爲存儲器塊分配不同的指針值。

MSDN中的頁面狀態注意全局函數比其他內存管理函數具有更大的開銷並提供更少的功能。除非文檔聲明應該使用全局函數,否則新的應用程序應該使用堆函數。這意味着,除非需要使用GlobalAlloc,否則MicroSoft建議使用HeapAlloc系列功能。從MSDN

參考文獻: GlobalAlloc function Comparing Memory Allocation Methods

+0

是的,我正在開發Windows平臺。並感謝您的回答,我認爲這將有助於我的理解。 – 2015-04-03 01:39:22

相關問題