В настоящее время я делаю проект флаттера и мне нужно использовать ffi для вызова функции на c языке. После исследования необходимо создать расширение Pointer класса cstring, после того, как я его создаю, он замечает меня The class 'CString' can't extend Pointer
. Так что мне нужно импортировать определенную библиотеку или только определенная версия дартс может это сделать?
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'dart:ffi'; // For FFI
import 'dart:io' show Platform;
import "dart:convert";
final DynamicLibrary nativeAddLib =
Platform.isAndroid
? DynamicLibrary.open("libnative_add.so")
: DynamicLibrary.process();
typedef NativeEncrypt = Void Function(CString,CString,Int32);
typedef DartEncrypt = void Function(CString,CString,int);
final int Function(int x, int y) nativePlus =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_plus")
.asFunction();
final int Function(int x, int y) nativeMinus =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_minus")
.asFunction();
final int Function(int x, int y) nativeTimes =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_times")
.asFunction();
final int Function(int x, int y) nativeDivide =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_divide")
.asFunction();
final int Function(List<Int32>, int length) nativeTOTP =
nativeAddLib
.lookup<NativeFunction<Int32 Function(List<Int32>,Int32)>>("native_totp")
.asFunction();
var encrypt = nativeAddLib.lookupFunction<NativeEncrypt, DartEncrypt>("encrypt");
class NativeAdd {
static const MethodChannel _channel =
const MethodChannel('native_add');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
static String encryptFlutter(String value){
CString data = CString.allocate(value);
CString enResult = CString.malloc(100);
encrypt(data,enResult,100);
return CString.fromUtf8(enResult);
}
}
class CString extends Pointer<Int8> {
/// 开辟内存控件,将Dart字符串转为C语言字符串
factory CString.allocate(String dartStr, [Reference ref]) {
List<int> units = Utf8Encoder().convert(dartStr);
Pointer<Int8> str = allocate(count: units.length + 1);
for (int i = 0; i < units.length; ++i) {
str.elementAt(i).store(units[i]);
}
str.elementAt(units.length).store(0);
ref?.ref(str);
return str.cast();
}
factory CString.malloc(int size, [Reference ref]) {
Pointer<Int8> str = allocate(count: size);
ref?.ref(str);
return str.cast();
}
/// 将C语言中的字符串转为Dart中的字符串
static String fromUtf8(CString str) {
if (str == null) return null;
int len = 0;
while (str.elementAt(++len).load<int>() != 0);
List<int> units = List(len);
for (int i = 0; i < len; ++i) units[i] = str.elementAt(i).load();
return Utf8Decoder().convert(units);
}
}
Моя функция на C языке похожа на
#include <stdint.h>
#include "sub_lib.h"
int32_t native_plus(int32_t x, int32_t y) {
return x + y + getDigits();
}
int32_t native_minus(int32_t x, int32_t y) {
return x - y + getDigits();
}
int32_t native_times(int32_t x, int32_t y) {
return x * y + getDigits();
}
int32_t native_divide(int32_t x, int32_t y) {
return x / y + getDigits();
}
int32_t native_totp(int32_t x[], int32_t y) {
int32_t totp = 103355;
return x;
}
void encrypt(char *str, char *r, int r_len){
int len = strlen(str);
for(int i = 0; i < len && i < r_len; i++){
r[i] = str[i] ^ KEY;
}
if (r_len > len) r[len] = '\0';
else r[r_len] = '\0';
}