gpt4 book ai didi

java - 使用 Java JNA 调用 DLL 库

转载 作者:行者123 更新时间:2023-11-30 12:02:55 27 4
gpt4 key购买 nike

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

SDK 文档指出:

Call NET_DVR_STDXMLConfig to pass through the request URL: GET /ISAPI/AccessControl/UserInfo/capabilities?format=json for getting the person management capability to know the configuration details and notices.

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 时得到了一个空指针此外,我的调用返回了一条通用的“参数无效”错误消息。

非常感谢任何帮助。

提前致谢

最佳答案

欢迎使用 StackOverflow。

您的结构映射看起来不错。您没有列出 NET_DVR_XML_CONFIG_OUTPUT 的 SDK 结构或文档,因此我无法提供您期望的帮助。

您的 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"

你在 arraycopy 上得到了 NPE,因为你还没有为 struInput.lpRequestUrl 创建一个数组;它只是一个指针。您可能希望将该字符串缓冲区定义为 Memory 对象,而不是数组副本,然后将字符串复制到其中,例如,

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

为另一个参数传递 Structure 指针很好,但您需要设置 struInput.dwInBufferSize 以匹配该结构的 size()。如所写,您似乎在输入结构中为该缓冲区大小传递了大小 0(默认 int),这可能是无效参数的来源。或者您可能尚未完全初始化 NET_DVR_MIME_UNIT 结构,因为您将 String 保留为 null 且未设置其长度。

您还需要为 OUTPUT 结构定义您自己的缓冲区,与上面类似,并且由于您不知道字符串的完整大小,因此您可以放置​​一个最大值(我假设 MAX_XML_CONFIG_LEN 基于你正在尝试做的事情,但我没有阅读 DLL 文档)你必须在你的 dll 的头文件中找到的值。

最后一点——您可能应该尝试使用最新版本的 JNA,因为总会有改进和错误修复。

关于java - 使用 Java JNA 调用 DLL 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58112497/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com