JNA 中 GlobalAlloc 和 GlobalLock 的 return 值有什么区别
What is the difference of return value between GlobalAlloc And GlobalLock in JNA
当我使用 jna 时,GlobalAlloc 和 GlobalLock 都是 returns 指针,但我发现它们的性能好像不相等。
例如,
在下面的这个案例中,我发现 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。
我认为 pointer 和 pointer2 应该指向同一个地方。
//添加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
曾经 return 一个(16 位)句柄,它被 GlobalLock
转换为 32 位指针。
如果您通过使用 GHND = 0x42 作为第一个参数来请求可移动内存块,您仍然可以表现出类似的行为。如果您执行 GlobalAlloc
returns 一个(32 位)句柄,必须使用 GlobalLock
将其转换为真正的指针。可以在对 GlobalLock
- GlobalUnlock
.
的不同调用中为内存块分配不同的指针值
MSDN 中的页面指出 注意与其他内存管理函数相比,全局函数具有更大的开销并提供更少的功能。新应用程序应该使用堆函数,除非文档说明应该使用全局函数。 这意味着 MicroSoft 建议使用 HeapAlloc
系列函数,除非您被要求使用 GlobalAlloc
.
来自 MSDN 的参考资料:
GlobalAlloc function
Comparing Memory Allocation Methods
当我使用 jna 时,GlobalAlloc 和 GlobalLock 都是 returns 指针,但我发现它们的性能好像不相等。
例如,
在下面的这个案例中,我发现 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。 我认为 pointer 和 pointer2 应该指向同一个地方。
//添加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
曾经 return 一个(16 位)句柄,它被 GlobalLock
转换为 32 位指针。
如果您通过使用 GHND = 0x42 作为第一个参数来请求可移动内存块,您仍然可以表现出类似的行为。如果您执行 GlobalAlloc
returns 一个(32 位)句柄,必须使用 GlobalLock
将其转换为真正的指针。可以在对 GlobalLock
- GlobalUnlock
.
MSDN 中的页面指出 注意与其他内存管理函数相比,全局函数具有更大的开销并提供更少的功能。新应用程序应该使用堆函数,除非文档说明应该使用全局函数。 这意味着 MicroSoft 建议使用 HeapAlloc
系列函数,除非您被要求使用 GlobalAlloc
.
来自 MSDN 的参考资料: GlobalAlloc function Comparing Memory Allocation Methods