Как продлить указатель в дротике? - PullRequest
0 голосов
/ 27 марта 2020

В настоящее время я делаю проект флаттера и мне нужно использовать 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';
}
...