dna 0.5.3

  • README.md
  • CHANGELOG.md
  • Installing
  • Versions
  • 50

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

CDartConstantIn/OutComments
voidvoidVOIDIn
charintC_CHARIn
shortintC_SHORTIn
intintC_INTIn
longintC_LONGIn
longlongintC_LONGLONGIn
boolboolC_BOOLIn
floatdoubleC_FLOATIn
doubledoubleC_DOUBLEIn
---------------
{type} *intC_POINTERInRaw pointer value.
{type} *TypedDataTYPEDDATAIn\OutTypeData must be initialized and have expected by callee size.
---------------
struct *TC_STRUCTInT is struct class. See Define structure.
struct *Ref<T>C_STRUCTOutT is struct class. See Define structure.
------------
char *StringC_STRINGIn
char *Ref<String>C_STRINGOut
char **List<String>LISTSTRINGIn
{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

Changelog

0.5

  • Refactoring
  • Fixed-length data types support

0.4

  • Refactoring
  • Improve performance

0.3

  • Nested structure support

0.2

  • Structure support

0.1

  • Initial version

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  dna: "^0.5.3"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:dna/dna.dart';
        
Version Uploaded Documentation Archive
0.5.3 Apr 20, 2018 Go to the documentation of dna 0.5.3 Download dna 0.5.3 archive
0.5.2 Apr 8, 2018 Go to the documentation of dna 0.5.2 Download dna 0.5.2 archive
0.5.1 Apr 7, 2018 Go to the documentation of dna 0.5.1 Download dna 0.5.1 archive
0.5.0 Apr 6, 2018 Go to the documentation of dna 0.5.0 Download dna 0.5.0 archive
0.4.0 Dec 31, 2016 Go to the documentation of dna 0.4.0 Download dna 0.4.0 archive
0.3.0 Dec 29, 2016 Go to the documentation of dna 0.3.0 Download dna 0.3.0 archive
0.2.2 Dec 28, 2016 Go to the documentation of dna 0.2.2 Download dna 0.2.2 archive
0.2.1 Dec 27, 2016 Go to the documentation of dna 0.2.1 Download dna 0.2.1 archive
0.2.0 Dec 26, 2016 Go to the documentation of dna 0.2.0 Download dna 0.2.0 archive
0.1.0 Dec 24, 2016 Go to the documentation of dna 0.1.0 Download dna 0.1.0 archive

All 12 versions...

Analysis

We analyzed this package on Apr 20, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.46.0
  • pana: 0.10.6

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
0 / 100
Health:
Code health derived from static analysis. [more]
99 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
50
Learn more about scoring.

Platforms

Detected platforms: other

Primary library: package:dna/dna.dart with components: nativewrappers, mirrors.

Suggestions

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 8 hints.

    Run dartfmt to format lib/src/dynamic_library.dart.

    Run dartfmt to format lib/src/meta.dart.

    Similar analysis of the following files failed:

    • lib/src/util.dart (hint)
  • Maintain an example.

    None of the files in your example/ directory matches a known example patterns. Common file name patterns include: main.dart, example.dart or you could also use dna.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.0.0 <2.0.0
Dev dependencies
test >=0.12.0 <0.13.0