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等数字。

不要尝试“使用数字”,因为您可能会遇到随机行为

正如我在integer
vtblId
中提到的,
\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);
}

顺便说一下,由于Windows
LONG
类型始终为32位,因此您还可以将第二个映射简化为:

public HRESULT SetContext(int lContext) { ... }
不要试图“玩弄数字”,因为你可能会经历随机行为

正如我在integer
vtblId
中提到的,
\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);
}

顺便说一下,由于Windows
LONG
类型始终为32位,因此您还可以将第二个映射简化为:

public HRESULT SetContext(int lContext) { ... }