是否可以使用 JNA/JNI 访问本机 COM/DirectX API 方法?
Is it possible to use JNA/JNI to access native COM/DirectX API methods?
我正在尝试使用 JNA 调用本机 Windows 方法:
HRESULT WINAPI DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN pUnkOuter );
但我真的很难理解在 Java 方面我应该使用什么作为参数。使用 JNA,您应该创建 Java classes 匹配本机 C 结构,我已经成功地使用 WinAPI.
的其他部分完成了此操作
根据我(我认为)到目前为止的理解,LPDIRECTSOUND 是 "Long pointer to a DirectSound struct" 的类型定义,而 LPUNKNOWN 是 "Long pointer to an Unknown"?
的类型定义
我在 DSound.h 中找到了原生结构 IDirectSound 和 IUnknown。我应该使用这些吗?然而,我找不到关于这些结构包含什么的规范,所以当我尝试将它们镜像为空的 classes 扩展 Java 侧的结构时,我得到
IllegalArgumentException: Structure class se.abjorklund.win32.jna.dsound.IDirectSound has unknown or zero size (ensure all fields are public)
所以这显然行不通。我猜我在这里遗漏了一些基本的东西,也许它与我不理解的 COM/Direct API 有关,并且像 "go read up" 这样的答案很酷,只要因为我可以获得有关阅读内容的指示!
下面是我尝试使用 JNA 移植到 Java 的 C 程序的工作片段。
LPDIRECTSOUND directSound;
if (directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))
所以在 C 中,您只需传递一个指向 LPDIRECTSOUND 的指针。我想我需要制作一个 LPDIRECTSOUND class 扩展 Java 中的 JNA 结构 class?我是接近答案还是离答案还很远?
JNA 确实支持 COM,并且 com.sun.jna.platform.win32.COM
包中已经存在多个映射,包括 IUnknown
接口和相应的 Unknown
class 实现它。
您可以实现一个 IDirectSound
接口(可选)或通过扩展 Unknown
直接实现 class。您将必须使用 _invokeNativeObject()
(或 -Int 和 -Void 变体)映射您需要的函数。
我在 WbemCli.java class 中贡献了几个查询 WMI 所需的 COM classes,它们可以作为如何传递这些参数的示例。 (注意:我可能不应该在具体的 classes 上使用 I
接口前缀,但现在已经太晚了。)
函数参数是 vtableId,参数的对象数组,以及 return 类型的 class。要获取 vtableId,您必须计算头文件中 directSoundVtbl
结构中的方法(从 0 开始)。我没有权威 Dsound.h 文件的副本,但这里有 one possibility 用于该排序(例如,CreateSoundBuffer
的 ID 为 3)。从 Unknown
继承已经获得了 Vtbl 中的前 3 个函数(id 的 0、1 和 2)。
这是一个(完全未经测试的)示例,可帮助您入门。
public interface DSound {
@FieldOrder ({ "dwSize", "dwFlags", ... })
class DSBUFFERDESC extends Structure {
public int dwSize;
public int dwFlags;
// continue conventional JNA Structure mapping here
// may have to map nested structures
}
class DirectSoundBuffer extends Unknown {
// methods invoking COM similar to below
}
class DirectSound extends Unknown {
public DirectSound() {
}
public DirectSound(Pointer p) {
super(p);
}
public HRESULT CreateSoundBuffer(DSBUFFERDESC lpcDSBufferDesc, DirectSoundBuffer lplpDirectSoundBuffer, Unknown pUnkOuter) {
// CreateSoundBuffer is 4th method of directSoundVtbl in Dsound.h
return (HRESULT) _invokeNativeObject(3,
new Object[] { getPointer(), lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter }, HRESULT.class);
}
// Map whatever functions you need, or all of them!
}
}
我正在尝试使用 JNA 调用本机 Windows 方法:
HRESULT WINAPI DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN pUnkOuter );
但我真的很难理解在 Java 方面我应该使用什么作为参数。使用 JNA,您应该创建 Java classes 匹配本机 C 结构,我已经成功地使用 WinAPI.
的其他部分完成了此操作根据我(我认为)到目前为止的理解,LPDIRECTSOUND 是 "Long pointer to a DirectSound struct" 的类型定义,而 LPUNKNOWN 是 "Long pointer to an Unknown"?
的类型定义我在 DSound.h 中找到了原生结构 IDirectSound 和 IUnknown。我应该使用这些吗?然而,我找不到关于这些结构包含什么的规范,所以当我尝试将它们镜像为空的 classes 扩展 Java 侧的结构时,我得到
IllegalArgumentException: Structure class se.abjorklund.win32.jna.dsound.IDirectSound has unknown or zero size (ensure all fields are public)
所以这显然行不通。我猜我在这里遗漏了一些基本的东西,也许它与我不理解的 COM/Direct API 有关,并且像 "go read up" 这样的答案很酷,只要因为我可以获得有关阅读内容的指示!
下面是我尝试使用 JNA 移植到 Java 的 C 程序的工作片段。
LPDIRECTSOUND directSound;
if (directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))
所以在 C 中,您只需传递一个指向 LPDIRECTSOUND 的指针。我想我需要制作一个 LPDIRECTSOUND class 扩展 Java 中的 JNA 结构 class?我是接近答案还是离答案还很远?
JNA 确实支持 COM,并且 com.sun.jna.platform.win32.COM
包中已经存在多个映射,包括 IUnknown
接口和相应的 Unknown
class 实现它。
您可以实现一个 IDirectSound
接口(可选)或通过扩展 Unknown
直接实现 class。您将必须使用 _invokeNativeObject()
(或 -Int 和 -Void 变体)映射您需要的函数。
我在 WbemCli.java class 中贡献了几个查询 WMI 所需的 COM classes,它们可以作为如何传递这些参数的示例。 (注意:我可能不应该在具体的 classes 上使用 I
接口前缀,但现在已经太晚了。)
函数参数是 vtableId,参数的对象数组,以及 return 类型的 class。要获取 vtableId,您必须计算头文件中 directSoundVtbl
结构中的方法(从 0 开始)。我没有权威 Dsound.h 文件的副本,但这里有 one possibility 用于该排序(例如,CreateSoundBuffer
的 ID 为 3)。从 Unknown
继承已经获得了 Vtbl 中的前 3 个函数(id 的 0、1 和 2)。
这是一个(完全未经测试的)示例,可帮助您入门。
public interface DSound {
@FieldOrder ({ "dwSize", "dwFlags", ... })
class DSBUFFERDESC extends Structure {
public int dwSize;
public int dwFlags;
// continue conventional JNA Structure mapping here
// may have to map nested structures
}
class DirectSoundBuffer extends Unknown {
// methods invoking COM similar to below
}
class DirectSound extends Unknown {
public DirectSound() {
}
public DirectSound(Pointer p) {
super(p);
}
public HRESULT CreateSoundBuffer(DSBUFFERDESC lpcDSBufferDesc, DirectSoundBuffer lplpDirectSoundBuffer, Unknown pUnkOuter) {
// CreateSoundBuffer is 4th method of directSoundVtbl in Dsound.h
return (HRESULT) _invokeNativeObject(3,
new Object[] { getPointer(), lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter }, HRESULT.class);
}
// Map whatever functions you need, or all of them!
}
}