World: r3wp
[Red] Red language group
older newer | first last |
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 | |
older newer | first last |