-
首页
-
ScanDoc Development
- J2534 指南
-
PassThru 函数说明
PassThruGetNextDevice v5.0
获取设备信息
最后修改:
说明
该函数依次返回在上一次调用
PassThruScanForDevices() 时找到的设备信息。每次调用返回列表中下一个设备的信息。每次新扫描时设备的顺序可能不同。
long PassThruGetNextDevice(SDEVICE* psDevice)
注意:在使用此函数之前无需调用 PassThruOpen()。只需事先调用 PassThruScanForDevices() 即可。
参数
- psDevice - 指向由应用程序分配的
SDEVICE 结构体的指针。函数执行成功后,该结构体将填充设备信息。
SDEVICE 结构体
typedef struct {
char DeviceName[80]; // 设备名称(ASCII,以 null 结尾)
unsigned long DeviceAvailable; // 设备可用状态
unsigned long DeviceDLLFWStatus; // DLL 与固件的兼容性
unsigned long DeviceConnectMedia; // 连接类型(有线/无线)
unsigned long DeviceConnectSpeed; // 连接速度(比特/秒)
unsigned long DeviceSignalQuality; // 信号质量(0-100%,未知时为 0xFFFFFFFF)
unsigned long DeviceSignalStrength; // 信号强度(0-100%,未知时为 0xFFFFFFFF)
} SDEVICE;
结构体字段说明
| 字段 |
说明 |
| DeviceName |
包含设备名称的 ASCII 字符串(最多 80 个字符,含 NULL 终止符)。该名称用于向用户显示,并应能唯一标识设备。示例:"ScanDoc FD #N4999"、"ScanDoc PRO (WLAN)" |
| DeviceAvailable |
设备的可用状态。参见取值表 |
| DeviceDLLFWStatus |
设备 DLL 与固件的兼容性状态。参见取值表 |
| DeviceConnectMedia |
与设备的连接类型。参见取值表 |
| DeviceConnectSpeed |
与设备的连接速度,单位为比特每秒 |
| DeviceSignalQuality |
信号质量,范围 0 到 100%。若未确定则值为 0xFFFFFFFF |
| DeviceSignalStrength |
信号强度,范围 0 到 100%。若未确定则值为 0xFFFFFFFF |
DeviceAvailable 的取值
| 常量 |
值 |
说明 |
| DEVICE_STATE_UNKNOWN |
0 |
无法确定设备状态 |
| DEVICE_AVAILABLE |
1 |
设备空闲且可供连接 |
| DEVICE_IN_USE |
2 |
设备已在使用中(被其他应用程序打开) |
DeviceDLLFWStatus 的取值
| 常量 |
值 |
说明 |
| DEVICE_DLL_FW_COMPATIBILTY_UNKNOWN |
0 |
无法确定 DLL 与固件的兼容性 |
| DEVICE_DLL_FW_COMPATIBLE |
1 |
DLL 与固件兼容 |
| DEVICE_DLL_OR_FW_NOT_COMPATIBLE |
2 |
DLL 或固件已过时或不兼容 |
| DEVICE_DLL_NOT_COMPATIBLE |
3 |
DLL 已过时或与设备不兼容 |
| DEVICE_FW_NOT_COMPATIBLE |
4 |
设备固件已过时或与 DLL 不兼容 |
DeviceConnectMedia 的取值
| 常量 |
值 |
说明 |
| DEVICE_CONN_UNKNOWN |
0 |
无法确定连接类型 |
| DEVICE_CONN_WIRELESS |
1 |
无线连接(WLAN、BLE) |
| DEVICE_CONN_WIRED |
2 |
有线连接(USB、Ethernet) |
函数调用顺序
PassThruScanForDevices(&count) → 获取设备数量
↓
for (i = 0; i < count; i++) {
PassThruGetNextDevice(&device) → 获取设备信息
}
↓
PassThruOpen(deviceName) → 打开所选设备
重要:应用程序无需对所有设备都调用
PassThruGetNextDevice()。可以在任意时刻停止遍历。但后续调用仍会继续返回列表中剩余的设备,直到列表结束、DLL 卸载或重新调用 PassThruScanForDevices()。
返回的错误码
| 代码 |
说明 |
可能原因及解决方法 |
| STATUS_NOERROR |
函数执行成功 |
psDevice 结构体已填充设备信息 |
| ERR_NULL_PARAMETER |
未指定 psDevice 指针 |
请传入指向 SDEVICE 结构体的有效指针 |
| ERR_EXCEEDED_LIMIT |
所有设备均已枚举完毕 |
- 所有已找到设备的信息均已返回
- 解决方法:调用
PassThruScanForDevices() 进行新的扫描
|
| ERR_BUFFER_EMPTY |
设备列表为空 |
PassThruScanForDevices() 未找到任何设备
PassThruScanForDevices() 未被调用
- 解决方法:调用
PassThruScanForDevices() 并检查 pDeviceCount
|
| ERR_CONCURRENT_API_CALL |
已有 J2534 API 函数正在执行 |
- 另一个 J2534 函数尚未执行完毕
- 解决方法:等待上一次调用完成
|
| ERR_NOT_SUPPORTED |
函数不受支持 |
- DLL 不支持设备的动态枚举
- 解决方法:直接使用
PassThruOpen()
|
| ERR_FAILED |
内部错误 |
- 使用
PassThruGetLastError() 获取详细信息
|
示例
C/C++ 示例
#include "j2534_dll.hpp"
unsigned long deviceCount = 0;
// 扫描设备
long ret = PassThruScanForDevices(&deviceCount);
if (ret != STATUS_NOERROR || deviceCount == 0)
{
printf("未找到设备\n");
return;
}
printf("找到设备数量: %lu\n", deviceCount);
// 遍历所有找到的设备
SDEVICE device;
for (unsigned long i = 0; i < deviceCount; i++)
{
ret = PassThruGetNextDevice(&device);
if (ret != STATUS_NOERROR)
{
break;
}
printf("\n设备 %lu:\n", i + 1);
printf(" 名称: %s\n", device.DeviceName);
printf(" 可用: %s\n",
device.DeviceAvailable == DEVICE_AVAILABLE ? "是" :
device.DeviceAvailable == DEVICE_IN_USE ? "占用中" : "未知");
printf(" 兼容性: %s\n",
device.DeviceDLLFWStatus == DEVICE_DLL_FW_COMPATIBLE ? "OK" : "需要更新");
printf(" 连接: %s\n",
device.DeviceConnectMedia == DEVICE_CONN_WIRELESS ? "无线" :
device.DeviceConnectMedia == DEVICE_CONN_WIRED ? "有线" : "未知");
if (device.DeviceSignalStrength != 0xFFFFFFFF)
{
printf(" 信号强度: %lu%%\n", device.DeviceSignalStrength);
}
}
// 连接到第一个可用设备
// (在实际应用中应让用户进行选择)
unsigned long deviceID;
ret = PassThruOpen(device.DeviceName, &deviceID);
if (ret == STATUS_NOERROR)
{
printf("\n已连接到: %s\n", device.DeviceName);
// ... 设备操作 ...
PassThruClose(deviceID);
}
Kotlin (Android) 示例
val j2534 = J2534JNI(context)
// 扫描设备
val scanResult = j2534.ptScanForDevices()
if (scanResult.status != STATUS_NOERROR || scanResult.deviceCount == 0) {
Log.w("J2534", "未找到设备")
return
}
// 收集所有设备的信息
val devices = mutableListOf<DeviceInfo>()
for (i in 0 until scanResult.deviceCount) {
val result = j2534.ptGetNextDevice()
if (result.status == STATUS_NOERROR) {
devices.add(result.device)
Log.i("J2534", """
设备 ${i + 1}:
名称: ${result.device.name}
可用: ${result.device.available}
信号: ${result.device.signalStrength}%
""".trimIndent())
}
}
// 显示设备选择对话框
showDeviceSelectionDialog(devices) { selectedDevice ->
val openResult = j2534.ptOpen(selectedDevice.name)
if (openResult.status == STATUS_NOERROR) {
// 设备操作...
}
}
Python (ctypes) 示例
from ctypes import *
import platform
# 加载库
if platform.system() == "Windows":
j2534 = windll.LoadLibrary("j2534sd_v05_00_x64.dll")
elif platform.system() == "Darwin":
j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")
else:
j2534 = cdll.LoadLibrary("libj2534_v05_00.so")
# 定义 SDEVICE 结构体
class SDEVICE(Structure):
_fields_ = [
("DeviceName", c_char * 80),
("DeviceAvailable", c_ulong),
("DeviceDLLFWStatus", c_ulong),
("DeviceConnectMedia", c_ulong),
("DeviceConnectSpeed", c_ulong),
("DeviceSignalQuality", c_ulong),
("DeviceSignalStrength", c_ulong)
]
# 常量
DEVICE_AVAILABLE = 1
DEVICE_IN_USE = 2
DEVICE_DLL_FW_COMPATIBLE = 1
DEVICE_CONN_WIRELESS = 1
DEVICE_CONN_WIRED = 2
# 扫描设备
device_count = c_ulong()
ret = j2534.PassThruScanForDevices(byref(device_count))
if ret != 0 or device_count.value == 0:
print("未找到设备")
exit()
print(f"找到设备数量: {device_count.value}\n")
# 获取每个设备的信息
devices = []
for i in range(device_count.value):
device = SDEVICE()
ret = j2534.PassThruGetNextDevice(byref(device))
if ret == 0:
devices.append(device)
name = device.DeviceName.decode('utf-8')
available = "是" if device.DeviceAvailable == DEVICE_AVAILABLE else \
"占用中" if device.DeviceAvailable == DEVICE_IN_USE else "?"
media = "WLAN/BLE" if device.DeviceConnectMedia == DEVICE_CONN_WIRELESS else \
"USB/LAN" if device.DeviceConnectMedia == DEVICE_CONN_WIRED else "?"
print(f"设备 {i + 1}:")
print(f" 名称: {name}")
print(f" 可用: {available}")
print(f" 连接: {media}")
if device.DeviceSignalStrength != 0xFFFFFFFF:
print(f" 信号: {device.DeviceSignalStrength}%")
print()
# 连接到第一个可用设备
if devices:
device_id = c_ulong()
ret = j2534.PassThruOpen(devices[0].DeviceName, byref(device_id))
if ret == 0:
print(f"已连接到: {devices[0].DeviceName.decode()}")
# ... 设备操作 ...
j2534.PassThruClose(device_id)
C# (P/Invoke) 示例
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SDEVICE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string DeviceName;
public uint DeviceAvailable;
public uint DeviceDLLFWStatus;
public uint DeviceConnectMedia;
public uint DeviceConnectSpeed;
public uint DeviceSignalQuality;
public uint DeviceSignalStrength;
}
public enum DeviceAvailable : uint
{
Unknown = 0,
Available = 1,
InUse = 2
}
public enum DeviceConnectMedia : uint
{
Unknown = 0,
Wireless = 1,
Wired = 2
}
class J2534
{
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruScanForDevices(out uint pDeviceCount);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruGetNextDevice(out SDEVICE psDevice);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruOpen(string pName, out uint pDeviceID);
[DllImport("j2534sd_v05_00_x64.dll")]
public static extern int PassThruClose(uint DeviceID);
}
// 使用方法:
uint deviceCount;
int ret = J2534.PassThruScanForDevices(out deviceCount);
if (ret != 0 || deviceCount == 0)
{
Console.WriteLine("未找到设备");
return;
}
Console.WriteLine($"找到设备数量: {deviceCount}\n");
var devices = new List<SDEVICE>();
for (uint i = 0; i < deviceCount; i++)
{
SDEVICE device;
ret = J2534.PassThruGetNextDevice(out device);
if (ret == 0)
{
devices.Add(device);
Console.WriteLine($"设备 {i + 1}:");
Console.WriteLine($" 名称: {device.DeviceName}");
Console.WriteLine($" 可用: {(DeviceAvailable)device.DeviceAvailable}");
Console.WriteLine($" 连接: {(DeviceConnectMedia)device.DeviceConnectMedia}");
if (device.DeviceSignalStrength != 0xFFFFFFFF)
Console.WriteLine($" 信号: {device.DeviceSignalStrength}%");
Console.WriteLine();
}
}
// 连接到第一个设备
if (devices.Count > 0)
{
uint deviceId;
ret = J2534.PassThruOpen(devices[0].DeviceName, out deviceId);
if (ret == 0)
{
Console.WriteLine($"已连接到: {devices[0].DeviceName}");
// ... 设备操作 ...
J2534.PassThruClose(deviceId);
}
}
相关函数