dna 0.1.0 dna: ^0.1.0 copied to clipboard
Dart Native Access.
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 arguments types and return type to C date types:
FIXME: Platform specific step
typedef int pid_t;
- Map C types to Dart types and DNA type constants:
FIXME: Decribe pointers and in/out arguments
C | Dart | DNA |
---|---|---|
void | void | ARG_VOID |
char | int | ARG_CHAR |
short | int | ARG_SHORT |
int | int | ARG_INT |
long | int | ARG_LONG |
longlong | int | ARG_LONGLONG |
bool | boool | ARG_BOOL |
float | double | ARG_FLOAT |
double | double | ARG_DOUBLE |
type * | Ref | ARG_POINTER |
- Define class
Libc
with annotation@Lib
:
@Lib('libc.so.6')
class Libc {
}
libc.so.6
is library name
FIXME: Symlinks aren't supported yet
- Define method
getppid
. Annotate arguments with@Arg
and method with@Ret
with corresponding type constants:
class Libc {
@Ret(ARG_INT)
int getpid() { ... }
}
- Finish with boilerplate code:
FIXME: This is temporary step for early versions
class Libc {
dynamic lib = new DynamicLibrary<Libc>();
int getpid() { return lib.getpid(); }
}
- Use it
Libc libc = new Libc();
var processId = libc.getpid();
Examples #
Linux #
libc library
@Lib('libc.so.6')
class Libc {
dynamic lib = new DynamicLibrary<Libc>();
int getpid() { return lib.getpid(); }
int getuid() { return lib.getuid(); }
int rand() { return lib.rand(); }
int rand_r(@Arg(ARG_POINTER) seedp) { return lib.rand_r(seedp); }
}
void main(){
Libc libc = new Libc();
var processId = libc.getpid();
print('pid $processId = ${io.pid}');
var userId = libc.getuid();
print('userId ${userId}');
libc.srand(0xDEADBEEF);
var rand = libc.rand();
print('rand $rand');
var seed = new Ref<int>(0xDEADBEEF);
var srand = libc.rand_r(seed);
print('rand with seed $srand');
}
Windows #
kenel32 library
@Lib('Kernel32.dll')
class Kernel32 {
dynamic lib = new DynamicLibrary<Kernel32>();
int GetCurrentProcess() { return lib.GetCurrentProcess(); }
int GetProcessId(@Arg(ARG_INT) int process) { return lib.GetProcessId(process); }
int GetModuleFileNameA(@Arg(ARG_INT) int process, @Arg(ARG_STRING) Ref<String> imageFileName, @Arg(ARG_INT) int size) { return lib.GetModuleFileNameA(process, imageFileName, size); }
bool GetProcessWorkingSetSize(@Arg(ARG_INT) int process, @Arg(ARG_POINTER) Ref<int> minimumWorkingSetSize, @Arg(ARG_POINTER) Ref<int> maximumWorkingSetSize) { return lib.GetProcessWorkingSetSize(process, minimumWorkingSetSize, maximumWorkingSetSize); }
int GetLastError() { return lib.GetLastError(); }
}
void main(){
Kernel32 kernel32 = new Kernel32();
var process = kernel32.GetCurrentProcess();
var processId = kernel32.GetProcessId(process);
print('pid $processId = ${io.pid}');
var min = new Ref<int>(0);
var max = new Ref<int>(0);
var result = kernel32.GetProcessWorkingSetSize(process, min, max);
print('working set min ${min.value} max ${max.value}');
var name = new Ref<String>(Strings.fill(' ', 64));
result = kernel32.GetModuleFileNameA(0, name, name.value.length);
print('module name ${name.value}');
}
Requirements #
- Linux 64-bit
- Windows 32-bit and 64-bit
Trade off #
- Performance?
- A lot of things aren't supported yet