www.dpdl.io
developed by SEE Solutions © 2003
Dpdl allows to access native 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 or native C/C++ libraries.
Dpdl library:
native
loadLib(string lib_name) return object lib
mapLib(string lib_name, object obj) return object lib
Example:
import('native')
object clib = loadLib("c")
clib.printf("This message comes from native printf function: %s %d", "Hello", 23)
By loading the library 'c', 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, 0x00)
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 = loadObj("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, 0x00)
println("char_dest is of type: " + typeof(char_src))
object size = loadObj("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 = loadObj("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 = loadObj("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
buffer.setMemory(0L, 4096L, 0x00)
The following tables lists the type mapping between C and Dpdl:
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'
The Dpdl native interface library is only available in the full registered version of 'DpdlEngine'.
A demo version with the 'native' library enabled can be requested for evaluation purposes by writing to: info@dpdl.io