World: r3wp
[Red] Red language group
older newer | first last |
jocko 17-Jun-2011 [2025] | I tried to write a console input function (no one is available up to now AFAK). This one works (for windows): #import [ "kernel32.dll" stdcall [ ReadConsole: "ReadConsoleA" [ handle [integer!] buffer [c-string!] len [integer!] read [struct! [value [integer!]]] reserved [integer!] return: [integer!] ] ] ] stdin: GetStdHandle WIN_STD_INPUT_HANDLE __read: struct [value [integer!]] input: func [s [c-string!] return: [c-string!] /local in][ ;in: "" ; don't work in: allocate 255 ; must be freed after ! prin s ReadConsole stdin in 255 __read 0 a: __read/value - 1; because of the line return symbol \n in/a: #"^(00)" ; necessary to add it ! in ] ; usage : res: input "enter a string : " print res my questions : - is this correct ? - how and where de-allocate the c-string ? - why the end-string symbol is not added automatically ? |
Kaj 17-Jun-2011 [2026x3] | My C library binding has a range of input functions |
I don't know if your code is correct, because it's Windows specific. It's quite possible that the Windows functions don't close strings with the trailing zero. My impression is that Windows wasn't originally built on the C standard library | |
The memory you allocate in your input function is returned from the function, so it must be freed outside the function, after every call | |
jocko 17-Jun-2011 [2029x2] | Have you tried the input functions of your C library binding ? I tried input-line (under windows) some time ago, and it did not work. At that time, i did not try to allocate the c-string |
Under windows, the problems with input-line (which uses gets) are probably the same as those that I faced in my implementation : to allocate the c-string buffer, to terminate the string properly. | |
Andreas 17-Jun-2011 [2031x3] | man gets: |
BUGS Never use gets(). | |
:) | |
jocko 17-Jun-2011 [2034] | I agree, should use fgets |
Kaj 17-Jun-2011 [2035x5] | Since this is open source, I was thinking to let the community do the testing. Thanks for the report :-) |
I was afraid the gets type functions are implemented as macros, so that may well be the problem. The thing is that I can't fix it by using the fgets type functions, because Red can't import the standard file descriptors such as stdin yet | |
We talked that over with Nenad and it's planned | |
input-next may have the same problem, but did you try it? | |
Strings are terminated properly with gets/input-line but you must allocate an unknown storage size, which is warned for in the source of the binding | |
Kaj 18-Jun-2011 [2040x3] | The binaries Red generates with a binding are now ten times as big as a few weeks ago, because it now generates code for #import definitions. Is that correct? |
When I have a struct! as a local variable, is only the pointer to the struct reserved on the stack, not the struct itself? | |
When I make a STRUCT for a local variable within a function, is it created on the heap, so that I need to free it? | |
Dockimbel 18-Jun-2011 [2043x5] | Bigger binaries: yes, it is caused by #import bindings and by runtime message strings. |
Local struct variable: that is correct, only the pointer is stored in the stack frame. | |
STRUCT is used to declare literal structures. As all literals, it is stored in the data segment of the executable image, you don't need to free it as it is not allocated with a malloc() call. | |
Kaj: have you found the "struct [...]" construction somehow misleading? I am asking this because there is a discussion about that on the mailing-list and I need to decide this weekend if I keep pointer/struct literal declarations as-is or change it. | |
Any feedback on this topic (and other opened questions on the ML and issue tracker) will be appreciated. | |
Kaj 18-Jun-2011 [2048x8] | I've been thinking about it, but the reason it is misleading is basically that it's defined at the C level. You have to flip flop your mind between low level C thinking and high level REBOL thinking |
I suppose this is inherent in the concept of Red/System, and I think it's mainly a matter of learning the new language | |
However, my own preference is to make concepts higher level if it doesn't compromise performance | |
It now dawns on me that I mixed up STRUCT and ALLOCATE. I hit these issues last night and went to bad because I was tired and pretty sure that I would be able to see it more clearly today, but I had already formulated the questions in my head :-) | |
to bed | |
The fact that I needed to allocate a local struct was pointed out to me by the new initialisation checks in Red, so that's pretty good | |
It would be nice to be able to use SIZE? on a datatype, instead of an actually existing data value: | |
size? integer! | |
Dockimbel 18-Jun-2011 [2056x2] | That might only be useful with integer! as it should be extended to 64-bit when Red/System will be ported to 64-bit platforms. But I think that a specific macro would be more appropriate (something like integer-size?). |
or rather: get-integer-size | |
Kaj 18-Jun-2011 [2058] | No, I simplified the example. I actually wanted to get sizes of structs without allocating one |
Dockimbel 18-Jun-2011 [2059] | Try with an alias (untested). |
Kaj 18-Jun-2011 [2060] | Doesn't it get the size of the pointer then? |
Dockimbel 18-Jun-2011 [2061x4] | Let me try... |
SIZE? doesn't seem to recognize the alias. | |
An alias is an abstract definition, it doesn't allocated anything. So we can decide that the size of an alias is the whole struct size. | |
allocated => allocate | |
Kaj 18-Jun-2011 [2065x7] | Yes, that's what I would like |
In the runtime, there's now a new generic pointer type defined: | |
#define byte-ptr! c-string! | |
However, it's type incompatible with the previous definition, which NULL still uses: | |
null: pointer [integer!] ;-- null pointer declaration | |
The documentation specifies a third definition, namely integer! | |
This comes back to the lack of a void pointer type again | |
Dockimbel 18-Jun-2011 [2072] | There is a ticket about null: https://github.com/dockimbel/Red/issues/96 |
Kaj 18-Jun-2011 [2073x2] | Failing that, I think these definitions should use the same type |
The new ALLOCATE and FREE use c-string! which makes using them on generic byte arrays, and comparisons with NULL, confusing | |
older newer | first last |