#InterprocesComm CygnusED
7 messages in this thread
I am using CygnusEd Pro editor, and am modifying some of thier
example routines to run the editor from outside the editor. The problem I
am having is not with the editor, but with interprocess comm.
In the following procedure, CurCEDMsg.rm_Result2 is a long, that is
a pointer to a string. If CurCEDMsg is either static, or global, then when
I use the printf to print the contents & address, I get both the correct
address, and the correct string, both inside, and outside the function
using what is returned by the function. However, if CurCEDMsg is LOCAL,
and not static then the string is garbage, and the number that the printf
prints is the length of the string!!
Also, I noticed that they don't use a GetMsg to get the message from
the port after Waiting. If I said GetMsg(MyPort), would that put the
message into CurCEDMsg ? Or would I have to say CurCEDMsg =
*GetMsg(MyPort) ? Or would that work at all? Or Am I VERY confused :^)
LONG SendCEDMsgGetStrReply(thecommand) char *thecommand; {
static struct CedMsg CurCEDMsg; /* Works fine */
LONG tmprep;
CurCEDMsg.cm_Args[0] = thecommand;
CurCEDMsg.cm_Node.mn_Node.ln_Type = NT_MESSAGE;
CurCEDMsg.cm_Node.mn_Length = sizeof(struct CedMsg);
CurCEDMsg.rm_Action = 1L << RXFB_RESUL; /* We do want results. */
CurCEDMsg.rm_Result2 = 0; /* clear out the last result. */
if (!(CedPort = FindPort("rexx_ced"))) return(FALSE);
if (!(MyPort = CreatePort("MyPort", 0L))) return(FALSE);
CurCEDMsg.cm_Node.mn_ReplyPort = MyPort;
PutMsg(CedPort, &CurCEDMsg);
WaitPort(MyPort);
DeletePort(MyPort); #ifdef DEBUG
printf("CurCEDMsg.rm_Result2 is %s.\n",CurCEDMsg.rm_Result2);
printf("CurCEDMsg.rm_Result2 eq %ld.\n",CurCEDMsg.rm_Result2);
printf("End GetStrReply.\n"); #endif
return(CurCEDMsg.rm_Result2); } main {
tmpstr = (char *)SendCEDMsgGetStrReply("status 19"); /* FileName */ current
file name into CurCEDMsg.rm_Result2 */ #ifdef DEBUG
printf("tmpstr eq %ld.\n",tmpstr); #endif
sprintf(tempstring, "okay1 'Current File Name' is \n'%s'.", tmpstr ); }
Question 1: Why do I get garbage is CurCedMsg is Local?
Answer 1: If CurCedMsg is local, it is by definition declared on the
run time stack known only to the currently executing sub-
routine. Once the routine returns to its caller, any local
data it may have maintained become undefined.
Question 2: Why doesn't the example SendCygnusEdMessageGetReply call
GetMsg to receive the reply?
Answer 2: Notice that the example routine creates and deletes a mes-
sage port each time it is invoked. Not particularly effic-
ient, but that's the way the example was written.
GetMsg is not called because the definition of the inter-
process communication protocol between ARexx and CED (at
least, I can't speak for all ARexx communications since I
am no ARexxpert, although I'd like to be) says that any
results from the interprocess communication will be placed
in rm_Result2 which is part of the message which the send-
er sent. The address of the message is, of course, already
known to the sender.
Here's where the example makes use of the assumption that
the port will not be used again…Since the port will not
be used again, and the message was ours to begin with and
we already know where to look for the results, why remove
the message at all?
If routine were to be recoded to reuse the same rXGbOnad1[jEb0gzc_l!S.{J s.)m#&Y^bc
R
(I think this S**** 2400 baud modem sucks!)
As I was saying, If the routine were to be recoded to reuse the same return
port, messages being returned to it would need to be removed.
I was not the author of the example, so I cannot explain why it was written
the way it was. But, the above is my understanding of your questions after
having looked at the manual for a few minutes.
Hope this helped.
(Hope I'm right!?)
Perry
Yes, I think it does, though I will have to digest it for a while to
really understand it. I guess what I'm trying to do is get rid of the
Global Msg, and use local var instead. Thats the way I learned to
program…use a global ONLY when necessary, otherwise, pass var between
function's. With that in mind, what would be the best way to modify those
routines to use local var, and still talk to CED? Thanks, Jim V.
One way would be to use a locally declared message and have your routine
return the long word that CED returns. If I remember correctly, you
returned a true or false value depending upon if the transmission was
succesful. Instead return rm_Result2.
If rm_Result2 is a number (ie: you were expecting a number) then the return
value of the routine becomes the number you were waiting for.
If rm_Result2 is a pointer (ie: you were expecting a pointer) then the
return value of the routine is the pointer you were waiting for. Since this
pointer points to memory declared by CED (NOT your program) you can assume
the pointer is valid. Remember, as documented, it is YOUR responsibility to
free the memory associated with the pointer.
That is exactly what I did in the example code I uploaded. Whenever the
ver is local, instead of rm_Result2 having an address in it, it has the
length of the string!! I know that sounds unbelevable, but that is what
happens. I send CED status 19, which should give me the current file name.
If CurCEDmsg is local, then INSIDE SendCEDmsgGetReply, rm_Result 2 is not
the address of the string, it is the length of the string. I changed files,
so the name was different, and the number in rm_result2 was allways the
length of the string, including the null. If I make CurCEDMsg a static,
then the rm_result2 has the address of the string in it, and everything
works fine. And thats all I changed, just made CurCEDMsg a static.
The only thing I can think of, is even though I am still inside
SendCEDMsgGetReply(), I wait for CED to reply, which must task switch? So
that is where rm_result2 is getting screwed up. *t WHY is it the LENGTH of
the string???
If you like I could upload the complete program, so you could take a lok
at all of it. Or since it is based on what ASDG put out with CED, can I
upload it? If you would like to see it and are willing, Let me know, and I
will upload it. As of now, I am going ahead with it as a static, And
hoping it will make more sense as time goes on.
BTW, What I am trying to do is write a program that will allow CED to
compile, link, and show errors from inside CED; making it more integrated.
But since I don't have Arexx, and want to learn about interprocess comm. I
thought it would be good to do it in C.
It is not so unnatural that you are getting the length of the string. ARexx
defines string pointers to be a pointer to the text of a string which
immediately follows a long containing the length of the string. That is, if
everything were working properly, if you decremented a string pointer by
one long word, you'd find the string's length.
You might want to mail me your source code of the routine in question via
easyplex. I'll take a look at it.
By the way, what plans do you have for your resulting work?
Perry,
OK, I'll try and easyplex it to you, though I have never done that before, so
it may take me a couple of tries.
I'm going to try and set it up so you can call the program, ( called CEDIntf)
so that you can pass it any number of par, and it will tell CED to do certain
things, depending on the number you pass it. For example, CEDintf 1 3 might
compile the file being edited, and then load the resulting error file int CED,
in a small view at the bottom, and then go to each error in the source file
Of course , this would be for Lattice, as that is what I use; But I then want
upload CEDointf, and the source to the PD, and then somone else could add more
functions, so CEDIntf 9 10 might tell the Manx compile to do the same thing. I
am also going to try and see if I can't get it to create temporary buffers for
files, so you can have a file in mem, but not in a current view. That's one of
the major complaints that I have with CED. ALL files must be in a view.
Sometimes I like to have a file out there, loaded and just switch back and
forth I guess that's the way the Emacs editor I used to use worked, and I got
used to it.
Other than that, and a few minor thing, I like CED a lot. It's very flexible,
powerful, without being unweildy. I havent found any feature's I nedd that
arent there, and lots I like that I didn't expect( like text formatting).
Thansk for taking the time, I appreciate it!