www.dpdl.io
developed by SEE Solutions ©
Dpdl allows to access native C/C++ library functions of any given loaded native shared library, seamlessly in the same way as ordinary dpdl functions.
This features makes Dpdl a complete and powerful programming language to interact also with low level system components and native libraries.
Dpdl library:
native
loadLib(string lib_name) return object lib
mapLib(string lib_name, object obj) return object libExample:
import('native')
object clib = native.loadLib("c")
clib.printf("This message comes from native printf function: %s %d", "Hello", 23)By loading the library 'c' (libc) , the Dpdl runtime automatically selects the appropriate library, on Linux/Unix/MAC 'libc' and on Windows 'msvcrt'.
On Windows systems it's possible also to access the system library 'kernel32' and it provides COM support for accessing a wide rage of windows components.
Example Dpdl code accessing the system library 'libc' functions:
import('native')
object libc = native.loadLib("c")
println("testing native interface with 'libc'...")
int uid = libc.getuid()
println("uid: " + uid)
int gid = libc.getgid()
println("gid: " + gid)
string env_java = libc.getenv("JAVA_HOME")
println("env java: " + env_java)
int page_size = libc.getpagesize()
println("page_size: " + page_size)
println("setting and getting an environment variable...")
string new_env = "MY_env"
int stat = libc.setenv(new_env, "this is env MEGA", 1)
println("status: " + stat)
println("getting env variable 'MY_env'...")
string new_env_val = libc.getenv("MY_env")
println("env value: " + new_env_val)
println("testing malloc...")
object ptr = libc.malloc(1024)
ptr.setMemory(0L, 1024L, 0x00B)
libc.free(ptr)
println("done")
println("testing file access...")
object fcntl = getObj("Fcntl")
int fh = libc.open("./Test/TestWrite.txt", fcntl.O_RDWR)
raise(fh, "Error in opening file")
string mydata_str = "this is the content MEGA I write to my file"
object sz = new("size_t")
sz.setValue(24)
println("data size: " + sz)
sz = libc.write(fh, mydata_str, sz)
println("data size written: " + sz)
println("testing memory copy...")
string mymem_data = "my data string to copy: MEGA"
object char_src = libc.malloc(1024)
char_src.setString(0L, mymem_data)
println("char_src is of type: " + typeof(char_src))
object char_dest = libc.malloc(1024)
char_dest.setMemory(0L, 1024L, 0x00B)
println("char_dest is of type: " + typeof(char_src))
object size = new("size_t")
size.setValue(1024L)
int comp = libc.memcmp(char_src, char_dest, size)
if(comp > 0)
println("'*char_dest' is less than char_src")
fi
object ptr_dest = new("PointerByReference")
ptr_dest.setValue(char_dest)
object ptr_content = ptr_dest.getValue()
println("before copy memory is: " + ptr_content.getString(0L))
println("copying from source buffer...")
object szm = new("size_t")
szm.setValue(1024L)
object p = libc.memcpy(char_dest, char_src, szm)
println("after copy memory is: " + ptr_content.getString(0L))
comp = libc.memcmp(char_src, char_dest, size)
if(comp == 0)
println("'*char_dest' and '*char_src' are EQUAL")
fi
println("done")Native memory can be allocated via the the 'libc' library function 'malloc', which returns a Pointer object.
Example in C using 'malloc':
#import <stdio.h>
...
void *buffer = malloc(4096 * sizeof(char));In Dpdl, the equivalent native memory can be allocated as follows:
import('native')
object clib = native.loadLib("c")
object buffer = clib.malloc(4096L)
# optionally we can also zero the memory buffer, this is equivalent of 'memset(...)' in C
buffer.setMemory(0L, 4096L, 0x00B)The following tables lists the type mapping between Dpdl and C:
| Dpdl type | Native type | Size | on Windows OS |
| char or byte | char | 8-bit integer | BYTE, TCHAR |
| short | short | 16-bit integer | WORD |
| char | wchar_t | 16/32-bit character | TCHAR |
| int | int | 32-bit integer | DWORD |
| bool | int | boolean value | BOOL |
| NativeLong (jna) | long | 32/64-bit integer | LONG |
| long | long long | 64-bit integer | __int64 |
| float | float | 32-bit FP | |
| double | double | 64-bit FP | |
| string | char* | C string | LPCSTR |
| Pointer (jna) | void* | pointer | LPVOID, HANDLE, LPXXX |
Unsigned types have the same mappings as signed types
Helper functions and platform specific features are available via the following API accessible with Dpdl:
The native library to be loaded needs to be available on the default system path or it's path must be configured in the configuration file 'DpdlEngine.ini' via the 'DPDL_NATIVE_LIB_PATH' variable.
The default configuration for 'DPDL_NATIVE_LIB_PATH' is set to './lib/addon'
Dpdl provides built-in support for memory protection useful to avoid segmentation faults and unexpected crashes.
By default the protection is enabled, it can be disabled by setting the variable 'DPDL_NATIVE_CODE_PROTECTION' to 'false' in the configuration file 'DpdlEngine.ini'
