dna 0.5.3 copy "dna: ^0.5.3" to clipboard
dna: ^0.5.3 copied to clipboard

outdatedDart 1 only

Dart Native Access lets you deal with native libraries from Dart with zero lines of C/C++ code. Just pure Dart.

DNA #

Dart Native Access lets you deal with native libraries from Dart with zero lines of C/C++ code. Just pure Dart.

How to ... #

For instance, you want to call getppid function from libc library on Linux.

  • Find method signature in documentation:
pid_t getpid(void);
  • Map parameters types and return type to C data types:
typedef int pid_t;
  • Map C data types to Dart types and DNA type constants. See Type mapping.

  • Define class Libc with annotation @Library:

@Library('libc.so.6')
class Libc {
  
}

libc.so.6 is library name

  • Define method getppid. Annotate parameters with @Param and method with @Method with corresponding type constants:
class Libc {
  int getpid();
}

In this example method has no parameters.

  • Finish with boilerplate code:
class Libc extends DynamicLibrary<Libc> {
  int getpid();
}

  • Use it
Libc libc = new Libc();
var processId = libc.getpid();

For full code see Examples.

How to define library #

@Library('name')
class Library DynamicLibrary<Library> {
    
}

name is the OS specific library name. For instance: libname.so or name.dll or libname.dylib.

Please see documentation for the target OS to know where dynamic linker searches for the library.

FIXME: Symlinks aren't supported

How to define method #

@Method(C_XYZ) T method(
  @Param(C_XYZ) T1 inParam, 
  @Param(C_XYZ, out: true) Ref<T2> outParam);

C_XYZ is C type constant. See Type mapping.

How to define structure #

@Struct()
class Struct {
    @Field(C_XYZ) T field;
}

Type mapping #

C Dart Constant In/Out Comments
void void VOID In
char int C_CHAR In
short int C_SHORT In
int int C_INT In
long int C_LONG In
longlong int C_LONGLONG In
bool bool C_BOOL In
float double C_FLOAT In
double double C_DOUBLE In
{type} * int C_POINTER In Raw pointer value.
{type} * TypedData TYPEDDATA In\Out TypeData must be initialized and have expected by callee size.
struct * T C_STRUCT In T is struct class. See Define structure.
struct * Ref<T> C_STRUCT Out T is struct class. See Define structure.
--- --- --- ---
char * String C_STRING In
char * Ref<String> C_STRING Out
char ** List<String> LISTSTRING In
{integer type} * List<int> C_{type} In
{integer type} * Ref<List<int>> C_{type} Out
{decimal type} * List<double> C_{type} In
{decimal type} * Ref<List<double>> C_{type} Out

Out parameters #

Out parameters must be marked as @Param(..., out: true)

Dart doesn't support parameters by reference. It's good but it's the cause of one challenge: callee cannot override parameter object. For instance, String parameter cannot be modified inside called method.

Therefore, it's needed to use wrapper object to emulate out parameters: Ref<T>.

FIXME: Describe pointers, in/out parameters, String parameters and TypedData parameters

FAQ #

  • I see Failed assertion: 'libraryPointer != 0

Dynamic linker cannot find the library. Check the library name.

  • I see Failed assertion: 'methodPointer != 0

Dynamic linker cannot find method in the library. Check the method name. Check that library exports the method.

  • My library is cross platform and has different name on each platform.

See example.

@Library('libname.so', 'name.dll')
class Library DynamicLibrary<Library> {

}
  • My library doesn't export functions or/and uses custom logic to get function pointer

See example.

@Library('name.dll')
class Library DynamicLibrary<Library> {
  Library() : super(getMethodPointer);

  static int getMethodPointer(DynamicLibrary that, Invocation invocation) {
    return ... //raw function pointer here
  }
}

Examples #

Linux #

libc library

@Library('libc.so.6')
class Libc extends DynamicLibrary<Libc>  {
  int getpid();

  int getuid();
  
  int getgid();

  int getgroups(int count, @Param(C_INT, out: true, list: true) Ref<List<int>> groups);
  
  int rand();
  
  int rand_r(@Param(TYPEDDATA) TypedData seedp);
  
  void srand(@Param(C_UINT) int seed);
}

void main() {
  var libc = new Libc();

  var processId = libc.getpid();
  print('pid $processId');

  var userId = libc.getuid();
  print('user id ${userId}');

  var groupId = libc.getgid();
  print('group id ${groupId}');

  var n = libc.getgroups(0, new Ref(new List()));
  var groups = new Ref<List<int>>(new List<int>.filled(n, 0));
  libc.getgroups(n, groups);
  print('groups ${groups.value}');

  libc.srand(0xDEADBEEF);
  var rand = libc.rand();
  print('random $rand');

  var seed = new Uint32List.fromList([0xDEADBEEF]);
  var srand = libc.rand_r(seed);
  print('random with seed $srand');
}

Windows #

kenel32 library

@Library('Kernel32')
class Kernel32 extends DynamicLibrary<Kernel32> {
  
  int GetCurrentProcess();

  int GetProcessId(@Param(C_INT) int process);

  int GetModuleFileNameA(
      @Param(C_INT) int process,
      @Param(C_STRING, out: true) Ref<String> imageFileName,
      @Param(C_INT) int size);

  bool GetProcessWorkingSetSize(
      @Param(C_INT) int process,
      @Param(TYPEDDATA) TypedData minimumWorkingSetSize,
      @Param(TYPEDDATA) TypedData maximumWorkingSetSize);

  int GetLastError();
}

void main() {
  Kernel32 kernel32 = new Kernel32();
  var process = kernel32.GetCurrentProcess();
  var processId = kernel32.GetProcessId(process);
  print('pid $processId = ${io.pid}');

  var min = new Uint32List(1);
  var max = new Uint32List(1);
  kernel32.GetProcessWorkingSetSize(process, min, max);
  print('working set min ${min} max ${max} error ${kernel32.GetLastError()}');

  var name = new Ref(new String.fromCharCodes(new List.filled(64, 0)));
  kernel32.GetModuleFileNameA(0, name, name.value.length);
  print('module name  ${name.value} error ${kernel32.GetLastError()}');
}

Please find more examples in examples/.

Requirements #

  • Linux 64-bit
  • Windows 32-bit and 64-bit

To Do #

  • Improve performance
  • A lot of things aren't supported yet
    • Platform independent types: int8, int16, int32, int64 etc.
    • Function pointers to Dart methods
    • Custom structure align
    • Unions
    • ...
  • Mac OS support
  • Refactor and clean up code
2
likes
0
pub points
0%
popularity

Publisher

unverified uploader

Dart Native Access lets you deal with native libraries from Dart with zero lines of C/C++ code. Just pure Dart.

Homepage

License

unknown (LICENSE)

More

Packages that depend on dna