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.