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

World: r3wp

[Red] Red language group

Pekr
11-Feb-2012
[4850x2]
maybe not, I found this: 

extern LSN_GETBRIGHT		fpGetBright	;
Does it mean, that the real func name is fpGetBright?
Kaj
11-Feb-2012
[4852]
I think so, but the C code is also doing an indirection through a 
function pointer, hence the fp
Pekr
11-Feb-2012
[4853x2]
But some functions  work although defined the same way. There might 
be some more functionality happenening under the hood, and who knows, 
that the code tries to return. OTOH the specs are clear enough - 
if it is supposed to return integer, then integer is simply an integer. 
And dialog windows work - I e.g. got dialoc saying "LED screen not 
found", so the GUI is inside the dlls ...
Never mind, I just wanted to try it in Red. Good way to become familiar 
with the system trying to use it for practical purpose. I might try 
to continue investigatin COM communication, but R2 serial communication 
is also not much to be desired :-)
Kaj
11-Feb-2012
[4855]
Are all C functions defined as pointers (with * and fp markers)? 
Can you give an example of a binding that works?
Andreas
11-Feb-2012
[4856]
typedef int (WINAPI *LSN_GETBRIGHT)()


^^ That defines LSN_GETBRIGHT to be another name for a pointer to 
a stdcall function that takes no arguments and returns an int. (WINAPI 
== __stdcall)

extern LSN_GETBRIGHT		fpGetBright	;


^^ That now is the actual "function", although held indirectly as 
a function pointer. So somewhere in a library is a fpGetBright value 
which holds a LSN_GETBRIGHT function pointer.


In C you can directly call that as e.g. `int brightness = fpGetBright();`. 
However, I fear in Red/System it's at the moment not possible to 
perform that call.
Pekr
11-Feb-2012
[4857x2]
sorry, sitting in the bar, running via team viewer on my htc sensation, 
so limited pc usability right now :-)
Andreas - interesting. How is that some functions being defined the 
same way work?
Andreas
11-Feb-2012
[4859]
No idea, which one works :) ?
Pekr
11-Feb-2012
[4860x2]
typedef bool (WINAPI *LSN_ISPOWER)(void);		//??????,???0?1?
typedef bool (WINAPI *LSN_POWER)(bool);			//??????,??0??,1??
typedef bool (WINAPI *LSN_ISLOCK)(void);			//????,???0?1?
typedef bool (WINAPI *LSN_LOCK)(bool);			//????,??0?1?
uff, team viewer had someproblem switching focus, or it was me :-) 
so, turning on and off the screen works ... not just a - led screen 
reacts ...
Andreas
11-Feb-2012
[4862x2]
Well, maybe there actually is a LSN_Power function in the DLL you 
are linking to :)
I'd directly look at the DLL's exports first, to see what's actually 
going on there. After that you can go looking for the corresponding 
definitions in C headers or docs.
Pekr
11-Feb-2012
[4864]
actually i have a whole app source fes, at least i think. but there 
is not much to look into, that is just an utility to parametrose 
led screen. I dont want to bother anyone with it, I thought you might 
see some obvious error i am doing, but apparently the issue is more 
complex ...
Kaj
12-Feb-2012
[4865x3]
The obvious error is that the C function names you're using are incorrect. 
As Andreas said, you probably happened to hit some functions by that 
name for the ones that do something
The complex issue is that the functions are imported through pointers. 
Red/System can use function pointers if you write wrapper functions 
and pass them the function pointers. But Red/System can't import 
simple values yet, only functions, so you can't import the function 
pointers the way the C code does
However, the functions may also be exported the normal way, in which 
case you wouldn't have to use the pointers, but you would have to 
find the names of the real functions. For fpGetBright I would look 
for GetBright for example
Pekr
12-Feb-2012
[4868x2]
Here's how they are defined:


fpIsPower		= (LSN_ISPOWER)GetProcAddress(g_hLedCtrlInst, "LSN_IsPower");

 fpPower			= (LSN_POWER)GetProcAddress(g_hLedCtrlInst, "LSN_Power");

 fpIsLock		= (LSN_ISLOCK)GetProcAddress(g_hLedCtrlInst, "LSN_IsLock");
	fpLock			= (LSN_LOCK)GetProcAddress(g_hLedCtrlInst, "LSN_Lock");

 fpGetBright		= (LSN_GETBRIGHT)GetProcAddress(g_hLedCtrlInst, "LSN_GetBright");


First three work, fpGetBright, which is wrapped as LSN_GetBright 
(as this is actual name in exports of DLL), does not work. They all 
look to me being defined the same way, no? How is that first three 
work?
btw - does that mean, that Red/System is still not generally good 
enough, to wrrap "any" C interfacing?
PeterWood
12-Feb-2012
[4870]
I guess you're correct;  Red/System is not generally good enough 
to wrap "any and all" C libraries yet.


What is most important to me about Red/System at this time is that 
it needs to be good enough to allow Red to be developed. I believe 
the addition of partial float support to Red/System was not absolutely 
essential for the development of Red though I'm sure it will help. 


There are lots of other improvements that could and will eventually 
be made to Red/System but they don't seem as important as work on 
Red ... at least to me.
Robert
12-Feb-2012
[4871]
Doc, take a look at how Lua does the C interface. It's really great. 
Both ways, simple and works.
Pekr
12-Feb-2012
[4872x2]
btw - is/will something like inlined/included C/ASM code be possible 
in Red/System?
Robert - is it about the interface of LUA done right, or about LUA 
being somehow close to C?
Geomol
12-Feb-2012
[4874x2]
The interface is done right.
Lua is a scripting language, probably closer to languages like Python 
(and REBOL), than to C.
Andreas
12-Feb-2012
[4876x2]
Lua's C interface design is not applicable to Red/System; it can 
provide inspiration for Red, but I think the plan is to interface 
with C/C-level code from Red via Red/System.
Re "inline C/ASM in Red/System":


Possible in general, yes. Neither planned (afaik) nor worth it (imo), 
at the moment. Remember that Doc's primary reason for Red/System 
is to use it to bootstrap/write Red.
Kaj
12-Feb-2012
[4878x10]
Possible Evolutions:
http://static.red-lang.org/red-system-specs-light.html#section-19.9
In very low level cases, it would help to interface to host platforms 
or hardware
Here's how they are defined:

fpIsPower		= (LSN_ISPOWER)GetProcAddress(g_hLedCtrlInst, 
LSN_IsPower");

 fpPower			= (LSN_POWER)GetProcAddress(g_hLedCtrlInst, "LSN_Power");

 fpIsLock		= (LSN_ISLOCK)GetProcAddress(g_hLedCtrlInst, "LSN_IsLock");
	fpLock			= (LSN_LOCK)GetProcAddress(g_hLedCtrlInst, "LSN_Lock");

 fpGetBright		= (LSN_GETBRIGHT)GetProcAddress(g_hLedCtrlInst, "LSN_GetBright");


First three work, fpGetBright, which is wrapped as LSN_GetBright 
(as this is actual name in exports of DLL), does not work. They all 
look to me being defined the same way, no? How is that first three 
work?"
I don't know whey they behave differently, but at least the LSN_GetBright 
C function name you used seems to be correct
What your binding still does differently than the C code is that 
the C code loads the functions dynamically, while Red #import embeds 
loader symbols in the executable format. I think GetProcAddress is 
the standard Windows function to load symbols manually at run time
The good news is that this is independent from the manual setup of 
the function pointers that the C code seems to use to pass the manually 
loaded functions to other program files. You should be able to duplicate 
the manual loading of the functions. It's likely that the functions 
that already work, which are early initialisation functions, happen 
to already be loaded by the library, while the other functions aren't
You should bind the GetProcAddress function (I think there are already 
Red/System Windows examples floating around that use it), find out 
how to get the value of the g_hLedCtrlInst library handle, and use 
them to load the functions like the C code does
Then for each function you have to write a Red/System wrapper function 
and pass it the function pointer as if it were a callback function, 
and call it. There are examples of such constructs in my bindings
There's not much still missing to have Red/System inferface to any 
C code. Basically just importing external variables and support for 
64 bits integers. I think 16 bits integers can be faked on most CPUs
Pekr
12-Feb-2012
[4888x2]
I think I understand what you think, but I got lost in translation 
:-) I will have to think about it few times and try to do some experiments.Thank 
for putting some time into the topic ...
I understand the first two steps, but I don't understand, how such 
a function wrapper in Red/System would look like ...
Kaj
12-Feb-2012
[4890x3]
Here's an example from the C library binding:
on-quit: function [  ; Register handler for normal program termination.
;	handler		[function! []]  ; Callback
	handler		[integer!]
	return:		[logic!]
][
	#either OS = 'Syllable [
		not as-logic _on-quit handler none none
	][
		not as-logic _on-quit handler
	]
]
Instead of passing the handler, you'd execute it directly
Pekr
12-Feb-2012
[4893x2]
hmm, as I am not loading the library myself (IIRC R2 had something 
like addres-of), but Red/System is doing so. I wonder, if there is 
a way of how actually get the library handle ...
hmm, I have installed PE Explorer. It can somehow display some DLL 
related info. In export table, I can see functions entry points. 
If I understand it correctly, those will be an offsets from address, 
to which the library is bound after loading?
Kaj
12-Feb-2012
[4895x5]
Basically, but that's not the method used when loading manually
If you can find the functions you need in there, it shouldn't be 
necessary to load them manually. If so, something else keeps your 
functions from working
If they're not in the list, that would explain why they don't work, 
because the manual loading is needed to pull them in at run time
Besides GetProcAddress, there's a set of a few function for loading 
libraries and symbols. You'd need to bind them and use them to load 
the library, which yields the library handle, and then load the functions. 
They're what load/library and make routine! in REBOL use
Not sure if the Windows symbol tables work like I said, so you'll 
have to try