当我使用jna时,GlobalAlloc和GlobalLock都返回Pointer,但是我发现它们两者的表现好像并不相等。
例如,
在下面的这种情况下,我发现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都应指向同一位置。
//添加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" });
}
}
最佳答案
我假设您正在Windows平台上工作。 GlobalXx
函数实际上是旧16位Windows的回忆。在那个(旧)时间中,GlobalAlloc
用于返回(16位)句柄,该句柄由GlobalLock
转换为32位指针。
通过使用GHND = 0x42作为第一个参数,如果您请求可移动存储块,您仍然可以表现出相似的行为。如果这样做,GlobalAlloc
返回一个(32位)句柄,必须使用GlobalLock
将其转换为真正的指针。可以在对GlobalLock
-GlobalUnlock
的不同调用中为存储块分配不同的指针值。
MSDN中的页面指出:与其他内存管理功能相比,全局功能具有更大的开销并提供更少的功能。除非文档指出应使用全局函数,否则新应用程序应使用堆函数。这意味着MicroSoft建议改为使用HeapAlloc
系列函数,除非需要使用GlobalAlloc
。
来自MSDN的参考资料:
GlobalAlloc function
Comparing Memory Allocation Methods