Skip to content

Commit

Permalink
Add an 'extern' attribute to struct!
Browse files Browse the repository at this point in the history
So that it can be used to refer to the external variable in a library.
The format is:

make struct! [
	[extern: [lib "sym"]]
	;struct definition
]

example code:
rebol []

ncurses: make library! %libncursesw.so

stdscr: make struct! compose/deep [
	[
		extern: [(ncurses) "stdscr"]
	]
	ptr [pointer]
]

print ["stdscr:" stdscr/ptr]

close ncurses
  • Loading branch information
zsx authored and hostilefork committed Oct 13, 2015
1 parent 458388d commit aabac58
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/boot/errors.r
Expand Up @@ -273,6 +273,7 @@ Access: [
permission-denied: [{permission denied}]
process-not-found: [{process not found:} :arg1]

symbol-not-found: [{symbol not found:} :arg1]
]

Command: [
Expand Down
1 change: 1 addition & 0 deletions src/boot/words.r
Expand Up @@ -211,6 +211,7 @@ pointer
addr
raw-memory
raw-size
extern
rebval

;routine
Expand Down
35 changes: 35 additions & 0 deletions src/core/t-struct.c
Expand Up @@ -439,6 +439,41 @@ static void parse_attr (REBVAL *blk, REBINT *raw_size, REBUPT *raw_addr)
raise Error_Invalid_Arg(attr);
break;

case SYM_EXTERN:
++ attr;

if (*raw_addr != 0) /* raw-memory is exclusive with extern */
raise Error_Invalid_Arg(attr);

if (!IS_BLOCK(attr)
|| VAL_LEN(attr) != 2) {
raise Error_Invalid_Arg(attr);
}
else {
REBVAL *lib;
REBVAL *sym;
CFUNC *addr;

lib = VAL_BLK_SKIP(attr, 0);
sym = VAL_BLK_SKIP(attr, 1);

if (!IS_LIBRARY(lib))
raise Error_Invalid_Arg(attr);
if (IS_CLOSED_LIB(VAL_LIB_HANDLE(lib)))
raise Error_0(RE_BAD_LIBRARY);
if (!ANY_BINSTR(sym))
raise Error_Invalid_Arg(sym);

addr = OS_FIND_FUNCTION(
LIB_FD(VAL_LIB_HANDLE(lib)), s_cast(VAL_DATA(sym))
);
if (!addr)
raise Error_1(RE_SYMBOL_NOT_FOUND, sym);

*raw_addr = cast(REBUPT, addr);
}
break;

/*
case SYM_ALIGNMENT:
++ attr;
Expand Down

0 comments on commit aabac58

Please sign in to comment.