World: r3wp
[Red] Red language group
older newer | first last |
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 [4895x6] | 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 | |
Hm, I'm not sure either if the wrapper function can currently be written like I said. You'd have to use the specific declaration as function! type for the function pointer, but the Red/System type checker may not currently support getting the function pointer in the right type | |
Pekr 12-Feb-2012 [4901] | Hmm, so in my case the situation in Red/System is even worse than possibly in R2 and World, where I could get such a handle from load/library directive, whereas in Red/System, what you describe, is writing completly separate layer. In fact, C's LoadLibrary is not difficult to handle, but still - a C level coding, which I thought is almost eliminated for wrapping purposes ... |
Kaj 12-Feb-2012 [4902x4] | All in all, if it's possible to load the functions manually, it should also be possible to import them at load time with the regular #import method. So something else may be wrong in the binding |
The Red/System situation is certainly not worse: it's the other way around. You can program manual loading with just a few well defined functions, the same that R2 and World use. But normally, you use automatic loading by the operating system, which is the standard and most efficient way to do it, and which R2 and World can't use because they execute bindings at run time | |
It's just that there is no ready binding for manual loading that, so you currently have to program it yourself | |
loading yet | |
Pekr 12-Feb-2012 [4906x2] | This is the code from LEDSet program: bool LoadLedCtrl(void) { g_hLedCtrlInst = LoadLibrary("LedCtrl.dll"); if (!g_hLedCtrlInst) { g_hLedCtrlInst = LoadLibrary("..\\LedCtrl.dll"); return false; } // fpIsPower = (LSN_ISPOWER)GetProcAddress(g_hLedCtrlInst, "LSN_IsPower"); |
So, if I would wrap LoadLibrary and GetProcAddress, I could get what you describe? :-) | |
Kaj 12-Feb-2012 [4908x3] | See, the library handle comes from the standard library loading function (well, Windows standard) |
Yes, that would make your binding work the same way as the C code, so if that doesn't work, you definitely know the problem is elsewhere | |
Can you show your complete #import specification and the definition of a function that doesn't work? | |
Pekr 12-Feb-2012 [4911x2] | #import [ "LedCtrl.dll" cdecl [ led-is-power?: "LSN_IsPower" [ return: [logic!] ] led-open-card: "LSN_OpenCard" [ return: [logic!] ] led-get-screen-number: "LSN_GetLedScrNumb" [ return: [integer!] ] led-set-power: "LSN_Power" [ power-on? [logic!] return: [logic!] ] led-get-brightness: "LSN_GetBright" [ return: [integer!] ] |
led-get-brightness is the first one to fail ... | |
Andreas 12-Feb-2012 [4913] | your lib uses stdcall, so better use stdcall instead of cdecl (though that's most likely not the culprit here) |
older newer | first last |