C Interoperability
For the ABI responsibilities and exact declaration rules, see Attributes, Directives, and Interoperability.
DQ is designed to call C libraries directly. Interop code normally combines
external declarations, C-compatible types, pointers, and #linklib.
External Functions
Declare C functions with [[external]].
func printf(fmt : ^char, ...) -> int [[external]]
When the DQ name should differ from the C symbol, pass the symbol name.
func c_fprintf(stream : pointer, fmt : ^char, ...) -> int [[external('fprintf')]]
Variable Arguments
C-style variadic functions use ....
[[external]] func printf(fmt : ^char, ...) -> int
printf("value = %d\n", 42)
Use C-compatible argument types and format strings that match the external ABI.
External Global Variables
External global variables can use the DQ declaration name or an explicit native symbol name.
var errno : int [[external]]
var libc_stdout : pointer [[external('stdout')]]
Embedded Strings
Use ^char, str.pchar, embstr, and embstr(n) for C-style strings.
func WriteStr(s : embstr):
var p : ^char = s.pchar
while p^ <> 0:
putchar(p^)
p += 1
endwhile
endfunc
embstr(n) declares exactly n bytes of fixed storage, including its zero
terminator; its maximum content length is n - 1.
var buf : embstr(127) = "hello"
str has an enforced trailing zero and can be passed with .pchar without
copying. Internal zero bytes are still possible; a C API using zero-terminated
semantics sees only the prefix before the first zero byte.
Generic Pointers
Use pointer for opaque C pointers.
[[external]] func fopen(path : ^char, mode : ^char) -> pointer
[[external]] func fclose(file : pointer) -> int
Cast to typed pointers before dereferencing.
Struct Layout
Use structs for C-compatible records when layout is known.
struct SPoint:
x : int32
y : int32
endstruct
Attributes such as [[packed]], [[align(n)]], and [[volatile]] are available
for low-level layout/access cases where supported by the compiler. Memory-mapped
register fields can use [[regrw]], [[regro]], and [[regwo]] for volatile
read/write, read-only, and write-only access respectively.
Linking Libraries
Use #linklib to request an external library.
#linklib('z')
[[external]] func zlibVersion() -> ^char
Standard Package Declarations
The stdpkg/libc modules provide some existing C declarations.
use libc/stdio
ABI Responsibility
DQ type checking verifies the DQ side of the declaration, but the programmer is responsible for matching the real C ABI: integer widths, pointer types, struct layout, calling convention, variadic arguments, ownership, and lifetime.