使用Java JNA调用DLL库

问题描述 投票:1回答:1

我有一个带有DLL库的SDK。我正在从Java 1.8和JNA v3.0.9调用库我在定义结构时遇到了麻烦

SDK文档指出:

调用NET_DVR_STDXMLConfig来传递请求URL:GET / ISAPI / AccessControl / UserInfo / capabilities?format = json,以使人员管理功能了解配置详细信息和注意事项。

NET_DVR_STDXMLConfig API调用定义为:

BOOL NET_DVR_STDXMLConfig(
LONG                         lUserID,
NET_DVR_XML_CONFIG_INPUT     *lpInputParam,
NET_DVR_XML_CONFIG_OUTPUT    *lpOutputParam
);

lpInputParam
[IN] Input parameters, refer to the structure NET_DVR_XML_CONFIG_INPUT for details.

lpOutputParam
[IN/OUT] Output parameters, refer to the structure NET_DVR_XML_CONFIG_OUTPUT for details.

NET_DVR_XML_CONFIG_INPUT结构的定义:

struct{
DWORD       dwSize;
void        *lpRequestUrl;
DWORD       dwRequestUrlLen;
void        *lpInBuffer;
DWORD       dwInBufferSize; 
DWORD       dwRecvTimeOut;
BYTE        byForceEncrpt;
BYTE        byNumOfMultiPart;  
BYTE        byRes[30];
}

dwSize
Structure size.

lpRequestUrl
Request URL (command) for implement different functions, and it is in string format.

dwRequestUrlLen
Request URL size.

lpInBuffer
Buffer for storing input parameters (request messages), see the input content details structure in NET_DVR_MIME_UNIT.

dwInBufferSize
Input buffer size.

dwRecvTimeOut
Receiving timeout, unit: ms, 0-5000ms (default).

byForceEncrpt
Whether to enable force encryption (the messages will be encrypted by AES algorithm for transmission): 0-no, 1-yes.

byNumOfMultiPart
Number of message segments: 0-invalid; other values-number of message segments, which is transmitted by the parameter lpInBuffer in the structure NET_DVR_MIME_UNIT.

NET_DVR_MIME_UNIT结构的定义是

struct{
  char     szContentType[32];
  char     szName[MAX_FILE_PATH_LEN/*256*/];
  char     szFilename[MAX_FILE_PATH_LEN/*256*/];
  DWORD    dwContentLen;
  char*    pContent;
  BYTE     byRes[16];
}

szContentType
Content type (corresponds to Content-Type field in the message), e.g., text/json. text/xml, and so on. The content format must be supported by HTTP.

zName
Content name (corresponds to name field in the message), e.g., name="upload".

szFilename
Content file name (corresponds to filename field in the message), e.g., filename="C:\Users\test\Desktop\11.txt".

dwContentLen
Content size.

pContent
Data point.

这是我到目前为止在Java中所做的:DLL调用和结构定义

//DLL native call
boolean NET_DVR_STDXMLConfig(int lUserID, Pointer lpInputParam, Pointer lpOutputParam);

public static class NET_DVR_XML_CONFIG_INPUT extends Structure
{
    public int      dwSize;
    public Pointer  lpRequestUrl;
    public int      dwRequestUrlLen;
    public Pointer  lpInBuffer;
    public int      dwInBufferSize;
    public int      dwRecvTimeOut;
    public byte     byForceEncrpt;
    public byte     byNumOfMultiPart;
    public byte[]   byRes = new byte[30];
    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("dwSize", "lpRequestUrl", "dwRequestUrlLen", "lpInBuffer", "dwInBufferSize", 
                "dwRecvTimeOut","byForceEncrpt","byNumOfMultiPart", "byRes");
    }       
}

public static class NET_DVR_XML_CONFIG_OUTPUT extends Structure {
    public int dwSize;
    public Pointer lpOutBuffer;
    public int dwOutBufferSize;
    public int dwReturnedXMLSize;
    public Pointer lpStatusBuffer;
    public int dwStatusSize;
    public byte[] byRes = new byte[32];
    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("dwSize", "lpOutBuffer",
                "dwOutBufferSize", "dwReturnedXMLSize", "lpStatusBuffer",
                "dwStatusSize", "byRes");
    }
}

public static class NET_DVR_MIME_UNIT extends Structure{
    public byte[] szContentType = new byte[32];
    public byte[] szName = new byte[MAX_FILE_PATH_LEN];
    public byte[] szFilename = new byte[MAX_FILE_PATH_LEN];
    public int dwContentLen;
    public String pContent;
    public byte[] byRes = new byte[16];

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("szContentType", "szName", "szFilename", "dwContentLen", "pContent","byRes");
    }               
}   

这是我的库调用

NET_DVR_XML_CONFIG_INPUT    struInput = new NET_DVR_XML_CONFIG_INPUT();
NET_DVR_XML_CONFIG_OUTPUT   struOuput = new NET_DVR_XML_CONFIG_OUTPUT();
String strInput = new String("GET /ISAPI/AccessControl/UserInfo/capabilities?format=json\r\n\"");
byte[] byInput = strInput.getBytes();
System.arraycopy(byInput, 0, struInput.lpRequestUrl, 0, byInput.length);        // Nullpointer exception
struInput.dwRequestUrlLen = byInput.length;
NET_DVR_MIME_UNIT mimeUnit = new NET_DVR_MIME_UNIT();
//mimeUnit.pContent = new Memory(MAX_XML_CONFIG_LEN);                       // Dont know what to put in here
struInput.lpInBuffer = mimeUnit.getPointer();
struOuput.dwOutBufferSize = MAX_XML_CONFIG_LEN;
struOuput.dwStatusSize = struOuput.dwOutBufferSize;     

struInput.write();  
struOuput.write();

NET_DVR_STDXMLConfig(userID,struInput.getPointer(), struOuput.getPointer());    // Getting a generic "parameters not valid" error msg

我不确定我的结构。设置requestURL时我获取了空指针另外,我的调用还返回一个通用的“参数无效”错误消息。

非常感谢您的帮助。

提前感谢

java c# api dll jna
1个回答
0
投票

欢迎使用StackOverflow。

您没有列出NET_DVR_XML_CONFIG_OUTPUT的SDK结构,但我发现了another library which maps it,看起来很匹配。

您的NET_DVR_STDXMLConfig方法调用可以得到改善。虽然它可以传递原始的Pointer值,但最好在其中传递适当的结构。 JNA将在方法参数中将它们自动视为它们的引用指针,并自动处理read()write()。所以这是一个更好的映射:

boolean NET_DVR_STDXMLConfig(int lUserID, 
    NET_DVR_XML_CONFIG_INPUT lpInputParam, NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);

[不确定为什么要执行new String("string");而不是仅使用原始的"string"

由于尚未为struInput.lpRequestUrl创建阵列,因此将NPE放在阵列副本上;它只是一个Pointer。您可能想将String缓冲区定义为Memory对象,而不是数组副本,然后将字符串复制到其中,例如,

Memory requestUrl = new Memory(strInput.length + 1); // add space for null
requestUrl.clear(); // ensure last byte is null
requestUrl.setString(0, strInput);
struInput.lpRequestUrl = requestUrl;
struInput.dwRequestUrlLen = requestUrl.size();

您将需要为其他Pointer参数做类似的事情。

同样,您需要为OUTPUT结构定义类似于上面的缓冲区,并且由于您不知道字符串的完整大小,因此您应该设置一个最大值(我假设MAX_XML_CONFIG_LEN基于您要执行的操作,但我尚未阅读DLL文档),您必须在DLL的头文件中查找of的值。

我不确定为什么在方法中要求使用NET_DVR_MIME_UNIT结构时为什么在您的代码中使用NET_DVR_XML_CONFIG_OUTPUT结构。映射根本不对齐。这可能导致您的“参数无效”错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.