I'm using FFI library to connect a DLL with a Flutter desktop application, but getting: "Failed to load dynamic library"

616 Views Asked by At
//random_number.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "randomnumber.h"

int main()
{
    int number = fetch_number();
    printf("Random number: %d\n", number);
    return 0;
}

int fetch_number()
{
    int c, n;
    srand(time(0));
    n = rand() % 100 + 1;
    return n;
}

//randomnumber.h:
int fetch_number();

//lib/shared/services/ffi/ffi.service.dart:
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef fetch_number_func = Int32 Function();
typedef FetchNumber = int Function();

class FfiService {
  int fetchRandomNumber() {
    try {
      final dyLib = DynamicLibrary.open('lib/library/windows/randomnumber.dll');
      final fetchNumberPointer = dyLib.lookup<NativeFunction<fetch_number_func>>('fetch_number');
      final number = fetchNumberPointer.asFunction<FetchNumber>();
      return number();
    } catch (exc) {
      print('Something went wrong in fetchRandomNumber ${exc.toString()}');
    }
    return 0;
  }
}

//lib/locator.dart:
import 'package:get_it/get_it.dart';
import 'shared/services/ffi/ffi.service.dart';

final GetIt locator = GetIt.instance;

void setupLocator() {
  locator.registerLazySingleton(() => FfiService());
}

//lib/main.dart:
import 'package:flutter/material.dart';
import 'locator.dart';
import 'shared/services/ffi/ffi.service.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // INIT SERVICE LOCATOR
  setupLocator();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final ffiService = locator<FfiService>();
    final val = ffiService.fetchRandomNumber();

    return Scaffold(
      appBar: AppBar(
        title: const Text('FFI Linux'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('Getting Value from C'),
            Text('Random Number : ${val.toString()}'),
            const SizedBox(height: 50),
          ],
        ),
      ),
    );
  }
}

//pubspec.yaml
dependencies:
  ffi: ^1.1.2
  get_it: ^7.2.0

//in android > AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

//in ios > Runner > Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>Access required to load dynamic library.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Access required to load dynamic library.</string>


I'm using FFI library to connect a DLL with a Flutter desktop application, but getting: "Failed to load dynamic library".

For the DLL, I wrote a C program to generate a random number

Then, in the Flutter project, I inserted the randomnumber.dll file in the lib/library/windows/ directory. I created a new directory inside lib and added a new file ffi.service.dart

But I am still getting the same error. How can I resolve this error?

0

There are 0 best solutions below