0

I have a C library and I call it from Dart using FFI. It does not work when the C library makes a system call (http). I built some examples with a C++ application and it works fine. In this example I also call the C library using dlopen (without linking) like Dart does.

The log output is:

[tcp @ 0x7f00a4084f80] Starting connection attempt to 179.184.214.178 port 80
[tcp @ 0x7f00a4084f80] Connection to tcp://qthttp.apple.com.edgesuite.net:80 failed: Interrupted system call
cannot open input: -4

Is there any special thing that a system call does not work with dart FFI ?

The Dart Code is below however I do not think it is the problem:


import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';
import 'dart:io' show Platform, Directory;
import 'package:path/path.dart' as path;

typedef VideoStreamCreateFuncNative = ffi.Pointer<ffi.Void> Function();
typedef VideoStreamCreateFunc = ffi.Pointer<ffi.Void> Function();

typedef VideoStreamReleaseFuncNative = ffi.Void Function(ffi.Pointer<ffi.Void>);
typedef VideoStreamReleaseFunc = void Function(ffi.Pointer<ffi.Void>);

typedef VideoStreamInitFuncNative = ffi.Void Function(ffi.Pointer<ffi.Void>);
typedef VideoStreamInitFunc = void Function(ffi.Pointer<ffi.Void>);

typedef VideoStreamOpenFuncNative = ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<Utf8>, ffi.Pointer<ffi.Void>);
typedef VideoStreamOpenFunc = void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<Utf8>, ffi.Pointer<ffi.Void>);

typedef VideoStreamInitWithArgsFuncNative = ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32);
typedef VideoStreamInitWithArgsFunc = void Function(ffi.Pointer<ffi.Void>, int, int, int, int);

class VideoStream 
{
    late ffi.Pointer<ffi.Void> _instance;
    late ffi.Pointer<ffi.Void> _propertiesInstance;

    late VideoStreamCreateFunc _create;
    late VideoStreamInitFunc _init;
    late VideoStreamReleaseFunc _release;
    late VideoStreamOpenFunc _open;

    late VideoStreamCreateFunc _createProperties;
    late VideoStreamInitFunc _initProperties;
    late VideoStreamInitWithArgsFunc _initPropertiesWithArgs;
    late VideoStreamReleaseFunc _releaseProperties;

    VideoStream()
    {
        String libraryPath = "/home/bruno/projects/sp-foundation2/build/lib/x86_64/libSpFoundation2.so";

        if (Platform.isLinux) 
        {
            //libraryPath = path.join(Directory.current.path, 'libSpDoundation2.so');
        }
        else if (Platform.isMacOS) 
        {
            libraryPath = path.join(Directory.current.path, 'libSpFoundation2.dylib');
        } 
        else if (Platform.isWindows) 
        {
            libraryPath = path.join(Directory.current.path, 'SpFoundation2.dll');
        }

        ffi.DynamicLibrary library = ffi.DynamicLibrary.open(libraryPath);

        _createProperties = library.lookupFunction<VideoStreamCreateFuncNative, VideoStreamCreateFunc>('sp_video_stream_properties_create');
        _initProperties = library.lookupFunction<VideoStreamInitFuncNative, VideoStreamInitFunc>('sp_video_stream_properties_init');
        _initPropertiesWithArgs = library.lookupFunction<VideoStreamInitWithArgsFuncNative, VideoStreamInitWithArgsFunc>('sp_video_stream_properties_init_args');
        _releaseProperties = library.lookupFunction<VideoStreamReleaseFuncNative, VideoStreamReleaseFunc>('sp_video_stream_properties_release');

        _propertiesInstance = _createProperties();
        int formatRGB = 2;
        int channels = 3;
        _initPropertiesWithArgs(_propertiesInstance, 800, 600, formatRGB, channels);
        
        _create = library.lookupFunction<VideoStreamCreateFuncNative, VideoStreamCreateFunc>('sp_video_stream_create');
        _init = library.lookupFunction<VideoStreamInitFuncNative, VideoStreamInitFunc>('sp_video_stream_init');
        _release = library.lookupFunction<VideoStreamReleaseFuncNative, VideoStreamReleaseFunc>('sp_video_stream_release');
        _open = library.lookupFunction<VideoStreamOpenFuncNative, VideoStreamOpenFunc>('sp_video_stream_open');

        _instance = _create();
        _init(_instance);
    }

    void open()
    {
        const url = 'http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8';
        final urlNative = url.toNativeUtf8();

        _open(_instance, urlNative, _propertiesInstance);

        malloc.free(urlNative);
    }

    void dispose() 
    {
        _release(_instance);
        _releaseProperties(_propertiesInstance);
    }
}

The constructor works fine, but the "_open" native function raises an error and the log output is above.

UPDATE: If I do a looping for 100 times the code works in any attempt near 60th.

Bruno Gallego
  • 27
  • 1
  • 9
  • Hardly anyone can help you. You need to specify Dart code and foreign code too. FFI (Foreign function interface). – mezoni Jun 25 '22 at 13:51
  • @mezoni The problem is not in the code. Using FFI is as simple as the examples in the internet. The FFI works fine! The C Library is called and the result is taken from Dart code. The problem is the process context of Dart Runtime FFI. – Bruno Gallego Jun 25 '22 at 14:00

0 Answers0