C68 Question

Anything QL Software or Programming Related.
Post Reply
swensont
Forum Moderator
Posts: 325
Joined: Tue Dec 06, 2011 3:30 am
Location: SF Bay Area
Contact:

C68 Question

Post by swensont »

I'm having an issue with C68 and not to sure what the solution is. To open a window here is the code:

chanid_t chan1;

chan1 = io_open("con_300x200a50x50",-1);

I then want to print to that window:

fprintf(chan1,"This is the main window\n");

When I compile this, I get an error that a long is not able to be converted into a pointer. chanid_t is a long and fprintf wants a pointer for an argument.

So, how does one get around this and print to the window?

Tim


User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: C68 Question

Post by mk79 »

Hi Tim.

Check out the "fusechid" function, it converts the QDOS handle to a FILE* pointer in order to use the C-lib functions on QDOS channels.

Cheers, Marcel


User avatar
janbredenbeek
Super Gold Card
Posts: 685
Joined: Wed Jan 21, 2015 4:54 pm
Location: Hilversum, The Netherlands
Contact:

Re: C68 Question

Post by janbredenbeek »

fprintf works at a different level than io_open. To use the standard C I/O functions you should open a channel using fopen() which returns a pointer to a C structure (FILE *fp) rather than a QDOS channel id.
If you still need to do some low-level I/O there are probably functions in C68 to get the channel id associated with a FILE * pointer but I don't know them off hand.

later, Jan.


User avatar
tofro
Font of All Knowledge
Posts: 3144
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: C68 Question

Post by tofro »

Tim,

a channel ID is simply something different than a FILE* pointer that fprintf() is expecting.

Most C compilers come with a library that handles I/O on three different levels:
  • Level 0 I/O - This is the QDOS level. You are using QDOS I/O function with next to no "comfort" offered by the library on top of that. Opening a channel or file works using functions like io_open. Those functions return and operate directly on QDOS channel IDs. I/O is unbuffered by the C library and directly uses QDOS (and, obviously, there's no support for formatted I/O beyond what QDOS offers).
  • Level 1 I/O - This is the C "system" level - Not much added to level 0, the function to open files or devices is called open() and returns an integer file handle, read() and write() provide basic I/O which is still unbuffered. This is not much different from the above method and can basically be ignored on the QL - mainly because it provides even less functionality than the above.
  • Level 2 I/O - The "real C" level. Files and devices are opened using fopen(), I/O is buffered (characters will only be sent to the channel if they are followed by a line feed or explicitly "pushed" by fflush()) in the C library. The "handle" you get by opening a file is not a simple integer or ID, but rather a pointer to a struct that holds all the C internal information on that channel. All the I/O functions that start with an "f" (like fprintf() and fseek(),...relate to such files. If you want formatted I/O, printing of floating point and integer values in different formats,..., this is the way to go. It does, however, also add a bit of a run-time overhead.
Mixing between the three levels is a bit problematic (using a lower level file call on an upper level file could for example confuse buffering), even if there are functions like "fusechid()" and "fgetchid()" that convert file handles across levels and should be done with great care, if necessary. Better decide on one of the file handling methods and stay within that family.

Your example will work best if you write it like

Code: Select all

#include <stdio_h>
...
FILE * f;
...
f = fopen ("con_300x200a50x50", "rw");
fprintf(chan1,"This is the main window\n");
...
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
swensont
Forum Moderator
Posts: 325
Joined: Tue Dec 06, 2011 3:30 am
Location: SF Bay Area
Contact:

Re: C68 Question

Post by swensont »

Marcel, Jan, Tobias,

Thanks for the input. Tobias, I see where you are going by using fopen, but I want to use routines like:

- sd_bordr - to set the border color
- sd_setpa - set paper color
- sd_setin - set ink color

I don't think I can do those with the non-QDOS C68 library calls. I'll try the fusechid command and see how that works.

My other option was to use Digital Precision C, and it used a file_id for both QDOS and C calls.

Thanks,

Tim


User avatar
ql_freak
Super Gold Card
Posts: 537
Joined: Sun Jan 18, 2015 1:29 am

Re: C68 Question

Post by ql_freak »

As Jan said use the function FILE *fusechid(chanit_t qdosChannel) to get a FILE pointer which is needed to use the C-I/O functions starting with f like fprintf(...).

But note the warning from the manual:

"Mixing C and QDOS INPUT/OUTPUT

If you wish to be able to use both C and QDOS level input/output calls to refer to the same file/device then it is imperative that you issue a 'setbuf' call (defined in stdio.h) to disable internal buffering within the C standard input/output routines. Failure to do this can result in input/output reacting in unexpected ways."

Another solution would be, that You use only QDOS I/O and if you need the power of printf() use sprintf which prints formatted output to a memory area, which you can then output via the simpler QDOS I/O functions.


http://peter-sulzer.bplaced.net
GERMAN! QL-Download page also available in English: GETLINE$() function, UNIX-like "ls" command, improved DIY-Toolkit function EDLINE$ - All with source. AND a good Python 3 Tutorial (German) for Win/UNIX :-)
Post Reply