Java 在JNA中调试COM接口映射
在将Java 在JNA中调试COM接口映射,java,com,jna,Java,Com,Jna,在将Vss.h和其他几个头映射到Java/JNA()之后,我试图运行一些COM对象方法,但调试它们时遇到问题 我不知道我调用的是正确的方法还是具有类似参数的方法。我在JNA文档中找到了一些错误代码,但它不包括我看到的所有错误 一些例子: // gather writer metadata public int GatherWriterMetadata(IVssAsync pAsync) { return _invokeNativeInt( 5, new Object[] { getPoi
Vss.h
和其他几个头映射到Java/JNA()之后,我试图运行一些COM对象方法,但调试它们时遇到问题
我不知道我调用的是正确的方法还是具有类似参数的方法。我在JNA文档中找到了一些错误代码,但它不包括我看到的所有错误
一些例子:
// gather writer metadata
public int GatherWriterMetadata(IVssAsync pAsync)
{
return _invokeNativeInt( 5, new Object[] { getPointer(), pAsync });
}
我有错误-2147212542
为了
我有
java.lang.Error:内存访问无效
位于com.sun.jna.Native.invokeInt(本机方法)
我尝试过在SetContext方法中使用31、32和33等数字。不要尝试“使用数字”,因为您可能会遇到随机行为
正如我在integervtblId
中提到的,\u invokenactive…
调用的值必须来自头文件中的Vtbl
结构。我没有直接访问头文件的权限,但可能使用起来很好,但由于此接口(以及所有COM接口)进行了扩展,它已经包含了函数QueryInterface()
、AddRef()
、和Release()
,这些函数占用了vtblId
您的GatherWriterMetadata
方法使用了5的vtblId
,实际上调用了InitializeForBackup()
函数,该函数需要一个BSTR
参数。您正在给它一些其他参数,因此它返回了一个错误。(如果通过十进制值-2147212542查找错误不起作用,则可以将其转换为2的补码十六进制,在本例中为0x80042302
,这是一个系统还原错误。)
据我计算,您应该使用9的vtblId
来表示gatherwritermatadata
。请自己数一数确认
根据我的统计,您的SetContext
方法应该使用35的vtblId
。再次,请计算功能的数量(从3开始)以确认这一点
另外,我看到您在这些函数中的大多数函数的返回类型中使用了int类型,而不是HRESULT
。由于HRESULT
最终是一个32位整数类型,因此这将起作用。但是,如果实际使用HRESULT
作为返回值,则可以访问更方便的/自文档化错误处理方法,如COMUtils.succeed()
和COMUtils.FAILED()
,甚至是COMUtils.checkRC()
方法,该方法在失败时抛出格式良好的COMException
因此,您的映射可能应该是:
// gather writer metadata
public HRESULT GatherWriterMetadata(IVssAsync pAsync)
{
return _invokeNativeObject( 9,
new Object[] { getPointer(), pAsync }, HRESULT.class);
}
及
顺便说一下,由于WindowsLONG
类型始终为32位,因此您还可以将第二个映射简化为:
public HRESULT SetContext(int lContext) { ... }
不要试图“玩弄数字”,因为你可能会经历随机行为
正如我在integervtblId
中提到的,\u invokenactive…
调用的值必须来自头文件中的Vtbl
结构。我没有直接访问头文件的权限,但可能使用起来很好,但由于此接口(以及所有COM接口)进行了扩展,它已经包含了函数QueryInterface()
、AddRef()
、和Release()
,这些函数占用了vtblId
您的GatherWriterMetadata
方法使用了5的vtblId
,实际上调用了InitializeForBackup()
函数,该函数需要一个BSTR
参数。您正在给它一些其他参数,因此它返回了一个错误。(如果通过十进制值-2147212542查找错误不起作用,则可以将其转换为2的补码十六进制,在本例中为0x80042302
,这是一个系统还原错误。)
据我计算,您应该使用9的vtblId
来表示gatherwritermatadata
。请自己数一数确认
根据我的统计,您的SetContext
方法应该使用35的vtblId
。再次,请计算功能的数量(从3开始)以确认这一点
另外,我看到您在这些函数中的大多数函数的返回类型中使用了int类型,而不是HRESULT
。由于HRESULT
最终是一个32位整数类型,因此这将起作用。但是,如果实际使用HRESULT
作为返回值,则可以访问更方便的/自文档化错误处理方法,如COMUtils.succeed()
和COMUtils.FAILED()
,甚至是COMUtils.checkRC()
方法,该方法在失败时抛出格式良好的COMException
因此,您的映射可能应该是:
// gather writer metadata
public HRESULT GatherWriterMetadata(IVssAsync pAsync)
{
return _invokeNativeObject( 9,
new Object[] { getPointer(), pAsync }, HRESULT.class);
}
及
顺便说一下,由于WindowsLONG
类型始终为32位,因此您还可以将第二个映射简化为:
public HRESULT SetContext(int lContext) { ... }