首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JNA 映射 C++ 指標參數結構體:NET_DVR_PlayBackControl_V40 實戰

     編輯:程式設計綜合問答

原始 C++ 簽名

BOOL NET_DVR_PlayBackControl_V40(
    LONG       lPlayHandle,
    DWORD      dwControlCode,
    LPVOID     lpInBuffer,      // 輸入結構體指標
    DWORD      dwInLen,
    LPVOID     lpOutBuffer,     // 輸出緩衝區指標
    DWORD*     lpOutLen         // 輸出長度指標
);

JNA 映射策略

C++ 類型JNA 類型說明
LONGNativeLong / int平台相關,通常 32-bit
DWORDint / NativeLong無號 32-bit
LPVOID (輸入結構體)Pointer / 結構體類別實例傳 Structure 實例,JNA 自動取址
LPVOID (輸出緩衝區)Pointer / Memory / 結構體實例預分配 Memory 或 Structure
DWORD* (輸出長度)IntByReference / NativeLongByReference傳遞引用,接收寫回值

完整 JNA 介面定義

import com.sun.jna.*;
import com.sun.jna.ptr.*;

public interface HikvisionSDK extends Library {
    HikvisionSDK INSTANCE = Native.load("HCNetSDK", HikvisionSDK.class); // Windows: HCNetSDK.dll
    
    // 輸入結構體
    class NET_DVR_COMPRESSION_INFO_V30 extends Structure {
        public byte byStreamType;
        public byte byVideoEncType;
        public byte byFormatType;
        // ... 其他欄位,務必按 C++ 定義順序完整列出
        @Override protected List getFieldOrder() {
            return Arrays.asList("byStreamType", "byVideoEncType", "byFormatType" /*, ...*/);
        }
    }
    
    // 輸出結構體 (若有)
    class NET_DVR_OUTPUT_PARAM extends Structure {
        public int dwSize;
        // ...
        @Override protected List getFieldOrder() { return Arrays.asList("dwSize" /*, ...*/); }
    }
    
    // 核心方法映射
    boolean NET_DVR_PlayBackControl_V40(
        NativeLong lPlayHandle,
        int dwControlCode,
        NET_DVR_COMPRESSION_INFO_V30 lpInBuffer,   // 直接傳結構體實例
        int dwInLen,
        NET_DVR_OUTPUT_PARAM lpOutBuffer,          // 預分配輸出結構體
        IntByReference lpOutLen                    // 接收實際輸出長度
    );
}

呼叫範例

public static void main(String[] args) {
    HikvisionSDK sdk = HikvisionSDK.INSTANCE;
    
    // 1. 準備輸入參數
    HikvisionSDK.NET_DVR_COMPRESSION_INFO_V30 inParam = new HikvisionSDK.NET_DVR_COMPRESSION_INFO_V30();
    inParam.byStreamType = 0;
    inParam.byVideoEncType = 1;
    inParam.byFormatType = 1;
    // ... 設定其他必要欄位
    
    // 2. 準備輸出緩衝區
    HikvisionSDK.NET_DVR_OUTPUT_PARAM outParam = new HikvisionSDK.NET_DVR_OUTPUT_PARAM();
    outParam.dwSize = outParam.size(); // 關鍵:告知 C++ 端緩衝區大小
    IntByReference outLen = new IntByReference(0);
    
    // 3. 呼叫
    NativeLong handle = new NativeLong(123); // 假設播放句柄
    int controlCode = 1; // 例如:暫停/繼續/設定壓縮參數
    
    boolean ok = sdk.NET_DVR_PlayBackControl_V40(
        handle, controlCode,
        inParam, inParam.size(),
        outParam, outLen
    );
    
    System.out.println("呼叫結果: " + ok + ", 輸出長度: " + outLen.getValue());
    // 讀取 outParam 欄位獲取回傳資料
}

關鍵避坑指南

  • 結構體記憶體對齊:JNA 預設按平台對齊。若 C++ 使用 #pragma pack(1),需在 JNA 類加 @Structure.FieldOrder 並確保無填充,或使用 Structure.ALIGN_NONE。
  • 指標 vs 結構體實例:輸入結構體直接傳實例 (JNA 自動 getPointer()),輸出緩衝區預分配實例 (JNA 填充)。
  • 字串編碼:C++ char* 對應 JNA String (預設平台編碼) 或 WString (Unicode)。結構體中固定長度字元陣列用 byte[] 或 char[]。
  • 回調函數:若涉及回調,需實作 Callback 介面並保持引用防 GC。
  • 庫載入路徑:確保 HCNetSDK.dll 及其依賴 (如 libeay32.dll, ssleay32.dll) 在 java.library.path 或系統 PATH 中。

結語

JNA 映射 C++ 指標參數的核心原則:**輸入結構體傳實例、輸出緩衝區預分配實例、長度/狀態輸出用 *ByReference**。嚴格對應 C++ 定義順序與對齊,配合 IntByReference/Memory 處理輸出參數,即可穩健呼叫海康/大華等廠商 SDK。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved