Flutter USB通信插件libusb_new的使用
Flutter USB通信插件libusb_new的使用
环境
- Windows(10)
- macOS
- Linux(Ubuntu 18.04 LTS)
使用
查看示例
特性和错误
请在问题跟踪器上提交功能请求和错误报告。
构建
准备 llvm(9+)
- Windows:
winget install -e --id LLVM.LLVM
- macOS:
brew install llvm
- Linux:
sudo apt install libclang-10-dev
构建 libusb_xxx.dart
Windows/Linux:
pub run ffigen
mv lib/libusb_new.dart lib/libusb64.dart
修改 timeval
为 timeval64
macOS:
pub run ffigen
mv lib/libusb_new.dart lib/libusb32.dart
修改 timeval
为 timeval32
贡献
准备 libusb.h
从 https://github.com/libusb/libusb/releases 下载 xxx
版本并解压 libusb.h
准备 libusb-1.0 动态库
Windows:
从 https://github.com/libusb/libusb/releases 下载 xxx
版本并解压
copy libusb-1.0.23\MS64\dll\libusb-1.0.dll libusb-1.0\
macOS:
从 https://homebrew.bintray.com/bottles/libusb-1.0.23.catalina.bottle.tar.gz 下载 xxx
版本并解压
cp libusb/1.0.23/lib/libusb-1.0.dylib libusb-1.0/
Linux:
从 http://old.kali.org/kali/pool/main/libu/libusb-1.0/ 下载 xxx
版本并安装
cp /lib/x86_64-linux-gnu/libusb-1.0.so.0.xxx libusb-1.0/libusb-1.0.so
示例代码
main.dart
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart' show calloc;
import 'package:libusb_new/libusb_new.dart';
// 加载动态库
final DynamicLibrary Function() loadLibrary = () {
if (Platform.isWindows) {
return DynamicLibrary.open(
'${Directory.current.path}/libusb-1.0/libusb-1.0.dll');
}
if (Platform.isMacOS) {
return DynamicLibrary.open(
'${Directory.current.path}/libusb-1.0/libusb-1.0.dylib');
} else if (Platform.isLinux) {
return DynamicLibrary.open(
'${Directory.current.path}/libusb-1.0/libusb-1.0.so');
}
throw 'libusb dynamic library not found';
};
// 初始化 libusb
final libusb = Libusb(loadLibrary());
void main(List<String> arguments) {
// 初始化 libusb
var initResult = libusb.libusb_init(nullptr);
if (initResult < 0) {
return;
}
// 获取设备列表指针
var deviceListPtr = calloc<Pointer<Pointer<libusb_device>>>();
listdevs(deviceListPtr);
calloc.free(deviceListPtr);
// 清理
libusb.libusb_exit(nullptr);
}
// 列出设备
void listdevs(Pointer<Pointer<Pointer<libusb_device>>> deviceListPtr) {
// 获取设备数量
var count = libusb.libusb_get_device_list(nullptr, deviceListPtr);
if (count < 0) {
return;
}
// 获取设备列表
var deviceList = deviceListPtr.value;
printDevs(deviceList);
libusb.libusb_free_device_list(deviceList, 1);
}
// 打印设备信息
void printDevs(Pointer<Pointer<libusb_device>> deviceList) {
// 分配内存用于存储设备描述符
var descPtr = calloc<libusb_device_descriptor>();
var path = calloc<Uint8>(8);
// 遍历设备列表
for (var i = 0; deviceList[i] != nullptr; i++) {
var dev = deviceList[i];
// 获取设备描述符
var result = libusb.libusb_get_device_descriptor(dev, descPtr);
if (result < 0) continue;
// 解析描述符
var desc = descPtr.ref;
var idVendor = desc.idVendor.toRadixString(16).padLeft(4, '0');
var idProduct = desc.idProduct.toRadixString(16).padLeft(4, '0');
var bus = libusb.libusb_get_bus_number(dev).toRadixString(16);
var addr = libusb.libusb_get_device_address(dev).toRadixString(16);
print('$idVendor:$idProduct (bus $bus, device $addr)');
// 获取端口信息
var portCount = libusb.libusb_get_port_numbers(dev, path, 8);
if (portCount > 0) {
var hexList = path
.asTypedList(portCount)
.map((e) => e.toRadixString(16).padLeft(2, '0'))
.join(':');
print(' path: $hexList');
}
}
// 释放内存
calloc.free(descPtr);
calloc.free(path);
}
更多关于Flutter USB通信插件libusb_new的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter USB通信插件libusb_new的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用libusb_new
插件进行USB通信的代码案例。这个插件允许Flutter应用与连接的USB设备进行通信。需要注意的是,libusb_new
是一个较为底层的库,使用它需要对USB通信有一定的了解。
首先,你需要在pubspec.yaml
文件中添加libusb_new
依赖:
dependencies:
flutter:
sdk: flutter
libusb_new: ^0.x.x # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来是一个简单的Flutter应用示例,展示如何使用libusb_new
插件来列出连接的USB设备并尝试打开一个设备进行通信。
import 'package:flutter/material.dart';
import 'package:libusb_new/libusb_new.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<UsbDevice> _devices = [];
UsbDevice? _selectedDevice;
@override
void initState() {
super.initState();
_listDevices();
}
Future<void> _listDevices() async {
final libusbContext = await Libusb.init();
try {
final devices = await libusbContext.listDevices();
setState(() {
_devices = devices;
});
} finally {
await libusbContext.exit();
}
}
Future<void> _openDevice(UsbDevice device) async {
final libusbContext = await Libusb.init();
try {
final handle = await libusbContext.openDeviceWithVidPid(device.vendorId, device.productId);
// 在这里你可以进行进一步的通信操作,例如读取/写入数据
// 例如: await handle.claimInterface(0); // 假设接口号为0
// await handle.bulkTransfer(...); // 执行数据传输
// 示例: 打印设备描述信息
print('Opened device: ${device.description}');
setState(() {
_selectedDevice = device;
});
} catch (e) {
print('Failed to open device: $e');
} finally {
await libusbContext.exit();
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter USB Communication'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text('Connected USB Devices:'),
SizedBox(height: 16.0),
Expanded(
child: ListView.builder(
itemCount: _devices.length,
itemBuilder: (context, index) {
final device = _devices[index];
return ListTile(
title: Text(device.description ?? 'Unknown Device'),
trailing: Icon(Icons.arrow_forward),
onTap: () => _openDevice(device),
);
},
),
),
if (_selectedDevice != null)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 16.0),
Text('Selected Device: ${_selectedDevice?.description ?? 'None'}'),
// 这里可以添加更多与已打开设备交互的UI元素
],
),
],
),
),
),
);
}
}
注意事项:
- 权限:在Android上,你可能需要在
AndroidManifest.xml
中添加USB权限,并处理运行时权限请求。 - 平台特定代码:
libusb_new
是一个跨平台库,但某些功能(如处理权限)可能需要平台特定的代码。 - 错误处理:示例代码中的错误处理较为简单,实际应用中可能需要更复杂的错误处理和恢复机制。
- 设备兼容性:确保你的设备支持libusb,并且驱动已经正确安装。
这个示例仅展示了如何列出设备和打开设备。实际的通信操作(如读取/写入数据)需要根据你的具体设备和通信协议来实现。