r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3 Extensions] REBOL 3 Extensions discussions

jocko
11-Aug-2010
[1439]
not tested with a101
Andreas
11-Aug-2010
[1440x3]
Sample extension works just fine for me with (Linux) A102.
But as parts of the extension API have changed, I don't think that'll 
be the case in general.
I.e. as soon as you use any of the RXI_* functions, as almost any 
"real" extension will, you'll have to recompile against the A102 
headers
Maxim
11-Aug-2010
[1443]
jocko, I had assumed you had recompiled them....


you must recompile them for A101 and up, many enums and offsets have 
changed, so they don't correspond anymore.
jocko
11-Aug-2010
[1444x2]
The external sample extension works partly (apart from several string 
and word functions, like t-word-map)I understand that I have to recompile, 
but  it's not so easy to find the proper headers. Furthermore, I 
am not sure that the old make-ext.r script which generates the init_block 
is still usable. It would be useful to actualize the external sample 
extension. By the way, where is the page giving the main changes 
from a101 (changes from char * to REBSER*, t-word-map etc) ? I am 
not able to find it out.
Having had a look to the extension pages of the R3 documentation, 
I see that the use of make-ext.r to generate the init_block is no 
more relevant.
Andreas
11-Aug-2010
[1446x5]
The necessary headers are in src/include/: reb-c.h, reb-ext.h, and 
reb-ext-lib.h
(In the hostkit, that is.)
And I fear that some parts of the extension docs are currently outdated.
Regarding the changes, Carl's official docs are here: http://www.rebol.com/r3/changes.html
My personal summary for the extensions API:

- A100 is basically the same as the previous extensions-only API 
release (A77).

- A101 adds map_word, word_of_string, words_of_object, get_field, 
set_field

- A102 adds make_image and gc_protect, renames the constants used 
for series_info from RXI_INFO_* to RXI_SER_* and adds RXI_SER_DATA
jocko
13-Aug-2010
[1451]
Andreas: thanks? With A100+, it seems that we need some other headers: 
ext-types.h, reb-defs.h (also present in src/include ). However, 
although they compile, it seems that they cannot be opened under 
r3 ( access error: cannot open %xxx.dll ... reason: none). I suspect 
the absence of a given #define flag, but not easy to debug. Anyway, 
I think that it would be useful  to clarify. If anybody already succeded, 
please give us the set of files and the config used. If not, could 
somebody do the test ?
Andreas
13-Aug-2010
[1452x3]
Jocko, here's an "add-mul" sample extension that works with A102: 
https://gist.github.com/bc820cc3eb301c79c1ef
Compiled with `gcc -shared -fpack-struct=4 -Isrc/include/ -o sample.so 
sample.c`.
You'll possibly want to adapt the -I, make sure it points to the 
A102 hostkit's src/include/ directory. For Win32, you'll also want 
"-o sample.dll".
jocko
13-Aug-2010
[1455]
thhanks, I will try. But my problem is not here. I have two concerns 
:  for the extensions dealing with strings (not the simple example 
where one reverse the order of chars), the compatibility is no more 
achieved (because of changes in the representation or processing 
of strings ?) Then I have to compile using the new headers. And when 
I do so, the extension is no more loadable (even a simple one like 
your example)
Andreas
13-Aug-2010
[1456x5]
I dont't follow.
The example I have given above needs to be compiled with the "new" 
headers, the headers of the A102 hostkit, that is.
And as demonstrated: it compiles _and_ loads just fine.
Note that while my sample.c it may _look_ just like the example given 
in http://www.rebol.com/r3/docs/concepts/extensions-making.html#section-2, 
it differs in that `RX_Call` takes three arguments instead of two.
I added a second file, sample2.c, to demonstrate working with strings 
in A102: https://gist.github.com/bc820cc3eb301c79c1ef#file_sample2.c

Also compiles and loads fine for me.
jocko
13-Aug-2010
[1461]
thanks, ill have a look
jocko
18-Aug-2010
[1462x2]
Well, I had the same problem that some months ago :  

 in my application, I must compile in c++, and there is a difference 
 in labelling the function calls in c and c++.  
The simplest solution is to modify a line in reb-ext-lib.h:  
#define RXIEXT _declspec(dllexport) to
#define extern "C" RXIEXT _declspec(dllexport) 

One shoud definitly insert in this header a condition like  
#ifdef _cplusplus   
 #define extern "C" RXIEXT _declspec(dllexport)
This done, everything works correctly
Gregg
18-Aug-2010
[1464]
So C++ name mangling was the issue?
jocko
18-Aug-2010
[1465]
yes
Gregg
18-Aug-2010
[1466]
Good to know. Thank for posting!
Robert
18-Aug-2010
[1467x2]
Yes, that's a good note. Should be used. I forward it to Carl.
Done.
ChristianE
21-Aug-2010
[1469]
http://www.rebol.com/r3/docs/concepts/extensions-making.html#section-17
says it's out of date and I'm really having trouble including words 
as symbols in a result block of an extension command. 

It works fine with an *INIT_BLOCK defined as


 const char *init_block = "REBOL [\nTitle: {Power Management}\nName: 
 power\nType: extension\nExports: [power-status]\n]\n"

     "lib-boot:           does [map-words words] ;-- Is that a good idea?\n"

     "words:             [ac-line battery remains of high low critical 
     charging]\n"
	    "map-words:    command [words [block!]]\n"
	    "power-status: command []\n"
;

if after IMPORT %power.dll I call SYSTEM/MODULES/POWER/LIB-BOOT.


Is there a way to have IMPORT automatically execute the LIB-BOOT 
code with a simple extension not included into the host code with 
host-kit?
Robert
21-Aug-2010
[1470]
Sorry, don't get what you want to do. You can run some init code 
when the extension is loaded.
ChristianE
21-Aug-2010
[1471x2]
I'm trying to return a block containg a word not taken from a commands 
arguments. Say, I want to return a block like [BATTERY CHARGING]: 

That works with

	u32 *word_ids = 0; // used to hold word identifiers
	enum power_words {W_POWER_BATTERY = 1, W_POWER_CHARGING};

	RXIEXT int RX_Call(int cmd, RXIFRM *frm, void *data) {
		/* .... */

		v.int32a = word_ids[W_POWER_BATTERY];
		RXI_SET_VALUE(s, pos++, v, RXT_WORD); 
		v.int32a = word_ids[W_POWER_CHARGING];
		RXI_SET_VALUE(s, pos++, v, RXT_WORD);
	
		/* .... */
   	}


only after importing the DLL I "manually" init the words with a MAP-WORDS 
command. I was thinking that IMPORT eventually triggers LIB-BOOT 
init-code from the INIT_BLOCK. It seems like the init code is not 
executed.
That MAP-WORDS command only does:

	word_ids = RXI_MAP_WORDS(RXA_SERIES(frm, 1));
	return RXR_TRUE;
Robert
21-Aug-2010
[1473]
How does your RX_Init look like?
ChristianE
21-Aug-2010
[1474x2]
RXIEXT const char *RX_Init(int opts, RXILIB *lib) {
    RXI = lib;
    if (lib->version == RXI_VERSION) return init_block;
    return 0;
}
Straight from the samples, since I have about zero knowledge of C 
and only am exploring how extensions work.
Robert
21-Aug-2010
[1476]
Ok, you need to make a call to your lob-boot function out of this 
init function.
ChristianE
22-Aug-2010
[1477]
Ouch! Now that problem above has a really simple solution: Just putting 
the module init code in the CONST CHAR *INIT_BLOCK works great:

	const char *init_block =
	    "REBOL [\n"
	        "Title:   {Power Management}\n"
	        "Name:    power\n"
	        "Type:    extension\n"
	        "Exports: [power-status capture-screen]\n"
	    "]\n"

     "words:          [ac-line battery remains of high low critical charging]\n"
	    "map-words:      command [words [block!]]\n"

     "power-status:   command [{Returns ac-line and battery status information.}]\n"

     "capture-screen: command [{Returns screenshot as an image.}]\n"
	    "map-words words\n";


The "magic" is the last line, where MAP_WORDS WORDS is evaluated 
ofter loading the module, that command inits the dll with the word 
ids used by the extension.
ChristianE
26-Aug-2010
[1478]
I have built a simple R3 extension for ODBC database access. Although 
more work needs to be done in the unicode area and configurable rowset 
max-rows retrieval as well as catching some GC-related bugs, basic 
functionality like selects, inserts, updates and statement parameters 
is there and working for most major types like LOGIC!, INTEGER!, 
DECIMAL!, TIME! and STRING! I have to test with more databases / 
odbc database drivers. 


I have, however, major problems in working with date values. I just 
don't manage to retrieve date values passed to a command or to return 
a proper date value. So, has anybody succeeded in working with date 
values and probably knows how to create, access and calculate them? 
Sadly, I've found no example code related to date values and there 
isn't much documentation too. Any info is greatly appreciated!
Pekr
26-Aug-2010
[1479]
absolutly cool :-)
Chris
26-Aug-2010
[1480]
Do you have some examples of the date values you get back with their 
actual value?
Anton
26-Aug-2010
[1481x2]
I would say it's absolutely necessary to find the definitions of 
the date values. Reverse engineering can work, but may hide subtle 
bugs, and take much longer before you're sure about the correctness 
of the implementation.
Where have you looked so far?
Pekr
26-Aug-2010
[1483]
If you mean that it is difficult or impossible to work with date 
values in extensions, bring the issue to Robert, who can communicate 
it with Carl, to get the answer ASAP imo ....
Anton
26-Aug-2010
[1484x2]
Ah, good question, now I think Christian meant the binary format 
of rebol's date! values, not any database's date format, which should 
be available as a string at least.
I suspect the passing of rebol date values may not have been implemented 
in R3 extensions yet (not that I've tried anything there yet).
ChristianE
26-Aug-2010
[1486x2]
I've looked in DevBase, but haven't asked questions there yet. I've 
scanned all the extensions documentation on DocBase and the header 
files in the host-lib/extension packages. 


I didn't even manage to read a date value in a simple command like 
   TEST-DATE: COMMAND [DATE [DATE!]]      About every member n the 
REBOL value c-union type seemed to only contain zero values.
I have no idea on how date values are stored in C, all that the docs 
say is that date values are 32 bit encoded date and time zone values, 
so I mainly tried with value.int32a but tried other members too. 
I have no idea about how the encoding is done and - as Anton said 
- I really don't want to reverse engineer it.
Anton
26-Aug-2010
[1488]
Hmm.. that doesn't look very promising.