dna 0.2.2 dna: ^0.2.2 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 parameters 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. 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 {
@Method(C_INT)
int getpid() { ... }
}
In this example method has no parameters.
- 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();
Type mapping #
FIXME: Describe pointers and in/out parameters
C | Dart | Constant | In/Out | Comments |
---|---|---|---|---|
void | void |
VOID | ||
char | int |
C_CHAR | ||
short | int |
C_SHORT | ||
int | int |
C_INT | ||
long | int |
C_LONG | ||
longlong | int |
C_LONGLONG | ||
bool | bool |
C_BOOL | ||
float | double |
C_FLOAT | ||
double | double |
C_DOUBLE | ||
type * | int |
C_POINTER | if you know raw pointer value |
type * | TypedData |
TYPEDDATA | TypeData must be initialized and have expected by callee size | |
---|---|---|---|---|
struct * | T |
TYPEDATA | In | where T is strut class. See Define structure |
|struct *|Ref<T>
|TYPEDATA|Out|where T is strut class. See Define structure|
|---|---|---|---|
|char *|String
|C_STRING|In||
|char *|Ref<String>
|C_STRING|Out||
|int *|List<int>
|LISTINT|In||
|int *|Ref<List<int>>
|LISTINT|Out||
|char **|List<String>
|LISTSTRING|In||
|char **|Ref<List<String>>
|LISTSTRING|Out||
Out parameters must be annotate with @Out
Define method #
@Method(XYZ)
T method(@Param(XYZ) P1 inParam, @Param(XYZ) @Out() Ref<P2> outParam)
Define structure #
@Struct()
class Struct {
@Field(XYZ)
T field;
}
Define library #
@Library('name')
class Library {
}
FIXME: Symlinks aren't supported yet
Examples #
Linux #
libc library
@Library('libc.so.6')
class Libc {
dynamic lib = new DynamicLibrary<Libc>();
int getpid() { return lib.getpid(); }
int getuid() { return lib.getuid(); }
void srand(@Param(C_UINT) int seed) { return lib.srand(seed); }
int rand() { return lib.rand(); }
}
void main(){
Libc libc = new Libc();
var processId = libc.getpid();
print('pid $processId');
var userId = libc.getuid();
print('user id ${userId}');
libc.srand(0xDEADBEEF);
var rand = libc.rand();
print('random $rand');
}
Windows #
kenel32 library
@Library('Kernel32.dll')
class Kernel32 {
dynamic lib = new DynamicLibrary<Kernel32>();
int GetCurrentProcess() { return lib.GetCurrentProcess(); }
int GetProcessId(@Param(C_INT) int process) { return lib.GetProcessId(process); }
int GetModuleFileNameA(@Param(C_INT) int process, @Param(C_STRING) @Out() Ref<String> imageFileName,
@Param(C_INT) int size) { return lib.GetModuleFileNameA(process, imageFileName, size); }
bool GetProcessWorkingSetSize(@Param(C_INT) int process,
@Param(C_POINTER) Ref<int> minimumWorkingSetSize,
@Param(C_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(new String.fromCharCodes(new List.filled(64, 0)));
result = kernel32.GetModuleFileNameA(0, name, name.value.length);
print('module name ${name.value} result $result error ${kernel32.GetLastError()}');
}
Requirements #
- Linux 64-bit
- Windows 32-bit and 64-bit
Trade off #
- Performance?
- A lot of things aren't supported yet