El mié., 1 ene. 2020 a las 19:57, ToddAndMargo (<toddandma...@zoho.com>) escribió:
> On 2020-01-01 01:58, JJ Merelo wrote: > > > > El mar., 31 dic. 2019 a las 21:56, ToddAndMargo via perl6-users (< > perl6-us...@perl.org>) escribió: > >> On 2019-12-31 09:17, JJ Merelo wrote: >> > Hi, >> > >> > El mar., 31 dic. 2019 a las 5:54, Todd Chester via perl6-users >> > (<perl6-us...@perl.org <mailto:perl6-us...@perl.org>>) escribió: >> > >> > Hi All, >> > >> > >> https://docs.raku.org/language/nativecall.html#Passing_and_returning_values >> > >> > Did anyone else discover the mistake, hopefully not the hard way >> like I >> > did. Anyone get weird gibberish printed out like I did? >> > >> > my$string="FOO"; >> > >> # The lifetime of this variable must be equal to the required lifetime of >> > # the data passed to the C function. >> > my$array=CArray[uint8].new($string.encode.list);v >> > >> > The mistake is that "C" strings are terminated by a chr(0) -- in >> > "C" terms chr(0) is called a nul or 0x00. >> > >> > If you don't terminate your C string, the reading functions keep >> > careening >> > until it finds a chr(0). You have to tack a chr(0) onto the end. >> > >> > my$array=CArray[uint8].new($string.encode.list); >> > $array [$array.elems] = 0; >> > >> > $array should be 70 79 70 0 not 70 79 79 >> > You can test this with `say "$array"` (include the quotes). >> > >> > Maybe JJ will pick up on this and get it fixed. >> > >> > >> > >> > I don't always read this list, but I do read issues. If you put it >> > there, it will be definitely get addressed when possible. >> > >> > -- >> > JJ >> >> >> Hi JJ, >> >> I have a rule about not posting to that list, so maybe >> > > I could answer that with I will not address issues that are not raised in > the GitHub repo (which is not a list, BTW), but anyway, here you go. The > thing is, first, that the example has little to do with the structure of > the string itself; it focuses on the fact that the string has to be > encoded. But anyway, let's check if that is true, with this little example: > > ------ >8 ---------- const-char.c ---------------------- > #include <stdio.h> > > void set_foo ( const char *foo) { > printf("%s", foo); > } > ----------------- 8< -------------------------------------- > > And this Raku script that uses it > > -------------------------- >8 --------------- null-terminated-or-not.p6 > -------------- > use NativeCall; > > my $string = "FOO"; > my $array = CArray[uint8].new($string.encode.list); > sub set_foo(CArray[uint8]) is native('const-char') { * } > set_foo( $array ); > ----------------- 8< -------------------------------------- > > This works without a glitch, printing FOO to the terminal. As a matter of > fact, $array.elems returns 3, so its "encode" is not actually adding any > null-termination at the end. I'm no expert in C myself, and have not been > for at least 25 years. But I know stackoverflow, which says ( > https://stackoverflow.com/a/1253336/891440) > > Why do C strings work this way? It's because the PDP-7 microprocessor, on > which UNIX and the C programming language were invented, had an ASCIZ > string type. ASCIZ meant "ASCII with a Z (zero) at the end." > > Is this the only way to store strings? No, in fact, it's one of the worst > ways to store strings. For non-trivial programs, APIs, operating systems, > class libraries, you should avoid ASCIZ strings like the plague. > > > Plagues are bad. Let's avoid them for the upcoming year. Other than that, > happy new year to every one. > > -- > JJ > > > Hi JJ, > > Wow, you spent a lot of time on that. Thank you! > > You are of course correct. > > The example works and that is the end of it. So no > mistake to be addressed. > Well, it doesn't work as such. It's a non-working, but syntactically correct, example. It works as illustration. > > You are a teacher. Would you have wrote that example > with out addressing the nature of a "C" string and why > it requires a nul at the end? > ... which it does not ... > > You are a teacher. Would you have given an example that > only worked in the example? > Well, I would have given an example about how to work with strings in the section where it would really be useful, probably in the native types page: https://docs.raku.org/language/nativetypes > > You are a teacher. What would you have made the > purpose of that document? To teach how to use the > module? Or so just put down things with no practical > application? "It is intuitively obvious and left up to > the student to figure out on his own?" > That's a tutorial page, so I would try and be as informative and actionable as possible. But the issue is that C strings needn't end with a null. > > This is what happens in reality when you do not add the > nul to the end of a "C" string. C just keep careening > until it finds a nul. Here you go: > > > > > Well, not really. That's what happens when you use non-null (or whatever) terminated strings in Windows, and probably in some specific context, which I guess is gtk in this case. In that case, you _do_ need null-terminated strings, as well as length in a data structure called GString https://developer.gnome.org/gtk-tutorial/stable/x2080.html Maybe that's not exactly your case, but we can't do a general tutorial about how to handle C strings in a Raku manual. Just do in Raku whatever your C library manual tells you to do. So you are 100% correct in your assertions. And why > this error will not be corrected. And a good example > of why I don't post there anymore. > It will not be corrected because it's not a documentation error. Also, using strings in the way your other (native) libraries need is just common sense, that goes without saying, or "is left as an exercise to the student". In general, you don't need to null-terminate strings, and that's what the example goes. Any wrapper to a native library which _does_ need that should specifically say so. Cheers JJ