>>
APLDN Home

>>
Events

>>
Trainings

>>
APL Books

>>
APLDN Links

>>
Discussion Groups

>>
Downloads

>>
Articles

>>
Library

>>
Learning Tools

>>
APLDN User IO

>>
APL2000.com




Features

Author Thread: Temporary []WCALL definition
davin.church
Temporary []WCALL definition
Posted: Sunday, May 16, 2004 6:37 PM (EST)

Here's something I run into occasionally, and it gets to be quite irritating.  I will be writing a new utility function that needs to make a ŒWCALL, but the API definition is not found in the ADF or INI.  I know that I can use 'W_Ini' to create a new entry to be stored in the INI, but since I'm writing a utility, I don't want to go arbitrarily modifying the user's INI file without permission.  In fact, since it might be running in an unknown environment, there might not be an INI file to write to, it might be shared across multiple users, or it might be on a read-only device.

 

Therefore, what I would like to have is a modified version of 'W_Ini' that does the same job to the in-memory tables, but doesn't write the definition permanently to disk.

 

Might we be able to get something like that added?


Comments:

Author Thread:
j.merrill
Temporary []WCALL definition
Posted: Sunday, May 16, 2004 10:38 PM (EST)
I know there are fewer examples, but most #WCALLs that aren't available in the ADF/INI are done as easily using #NA. (The #WCALL advantage is that the details of the routine's parameters and result is pre-defined.) As you can define a local function with #NA, you don't interfere with the user's INI file or have any such issue.

     

davin.church
Temporary []WCALL definition
Posted: Sunday, May 16, 2004 11:49 PM (EST)

Yes, but there are a number of restrictions with []NA, at least one of which always seems to get me.  For instance:

 

1) You can't use named constants (I can usually live with that).

2) You can't define structures (difficult, but doable).

3) You can't have structure arguments that contain pointers to other structures (even more difficult and you'd have to manage memory directly).

4) You can't get callbacks.

5) And what I ran into today ... No virtual entry points.

 

A variation on W_Ini (perhaps just a special symbol in the argument?) would solve all these problems at once, and it doesn't sound too difficult at all (roughly, a branch in the right place).

     

j.merrill
Temporary []WCALL definition
Posted: Monday, May 17, 2004 9:47 AM (EST)

I'll concede that []NA doesn't solve all problems, but it's an alternative in some situations, and you hadn't said you had considered it and found it lacking.

 

The named constants used by an API call that's not in the ADF file probably wouldn't be in the ADF file for use by #WCALL either -- would they?

 

Have there been #WCALL changes that allow structures with pointers to other structures to be handled without you managing memory directly?

 

Can't you get callbacks via #NA using W_CreateFilter?

 

With what API in particular are you having touble today?  I'm not sure what you mean by the term "virtual entry point."

 

If this feature gets built (and I'm not saying it shouldn't be), I think the syntax should be

  Œwcall 'W_Ini' '[tempcall] ...'

rather using a special symbol in the defn.

 

Finally, the "read-only .INI file" situation seems rather unlikely to me.  (If the app is running off a CD, why doesn't the app have the call in its ADF?)  It's not rude to write to even a shared .INI file if you use a variant on the API call name.  For example if the ADF doesn't have the SetFiddle API in it, when you make the call to put it in the INI file, use a different name and alias it to SetFiddle -- e.g.

  Œwcall 'W_Ini' '[call] dcSetFiddle B(I) alias SetFiddle lib ...'

 ("dc" being your initials; I'd use "jmSetFiddle")

 

Writing utilities that don't have any requirements from the environment isn't particularly easy.  Documenting the requirements that you have ("either a writable INI file or an ADF file including this defn of the SetFiddle API") would make your life easier.

 

Good luck!

     

davin.church
Temporary []WCALL definition
Posted: Wednesday, May 19, 2004 3:59 PM (EST)

Missing named constants can be gotten around in such situations (at the expense of readability).

 

IIRC, you can define a structure in the ADF that contains a pointer to another named structure (also in the ADF).  This doesn't work for callbacks, but I think it may work for direct calls.

 

The manual says (under []WCALL) that it can handle callbacks while []NA can't.

 

Look in your ADF.INI file for the keyword VIRTUAL, such as on IUnknown::QueryInterface, for examples of use.

 

I was trying to define an interface to undocumented function Shell_GetImageLists as virtual entry point #71 in Shell32.dll.  I now have a workaround for this particular issue, but the need to do this kind of thing in general is still valid.

 

If I used W_Ini (right now) in the way you suggested, would I not get a new section written to my INI file called [tempcall]?  I was thinking of something more along the lines of: 'W_Ini' '*[Call]...', or perhaps an optional argument to indicate it's nature, such as 'W_Ini' '[Call]...' 1 (or ... '')?

 

As for having a modified ADF on a CD, this would be reasonable if it were needed by the application as a whole.  But if I'm writing a utility function for people to copy into their applications, I don't want to require them to modify their ADF (or know how) in order to use & distribute this in their application.  I'd rather it "just work".

 

And there's more than one reason you might have a read-only or shared ADF file.  For instance, think of the situation where the interpreter is stored on a shared drive of a corporate LAN.  Most likely, that's a R/O drive for most users, and even if it wasn't you wouldn't want to be writing new definitions to it that not everyone would want to see.  (And I don't think that faking the name is a good idea in such a situation, even if you could do it effectively from a generic utility function point of view.)

 

I agree that it's difficult to write for an indeterminate environment, but I think it's important to do so for generic-use programs.  So I go out of my way to make my stuff work that way as much as possible.  I want life to be as easy as possible for the programmers using my tools and place as few requirements on them as I can.

     

Brian.Chizever
Temporary []WCALL definition
Posted: Tuesday, May 25, 2004 1:34 PM (EST)

My feeling about []wcall definitions is that they fall into three categories:

  1. permanent - I'm distributing an app and I want the definition there
  2. utility/sample - I'm distributing sample APL code to other APL developers and (possibly) need to update the INI/ADF
  3. temporary - I don't want the definitions around when I'm done

I think all of these have separate answers.  (I realize that this thread is really talking about the third case, but I want to cover the other two and you can't stop me <g>.)

 

1 - I'm distributing an application

We distribute an ADF with the app.  We rename apwr.exe to OurApp.exe and the adf becomes OurApp.adf.  We create the ADF before shipping the application.  (Anyone shipping a complete appliction and using []WCALL's that aren't in the one provided by APL2000 should know how to create their own ADF file.  We start with what's provided by APL2000 and then add our own stuff to it.)

 

2 - samples for other APL developers

This is like the stuff that's given out at the APL conferences.  The startup function of the sample updates the INI file.  I'll also usually include a function that will remove them from the INI file, but I don't call it.  The developer can use it to clean up their INI or, if they plan on using the utility, keep it in their INI.  If they plan to use it in their application, they can copy it out of the INI to get it into their ADF file for distribution.

 

3 - temporary

This is really stuff that you don't want around when you're done.  If it's something that can be done with []NA, I just use that.  If it can't be done with []NA (i.e. vtable or it has a callback) then I'll create entries in the INI file, but I'll give them unique names.  For example if I wanted to use SendMessage and it wasn't there, I'd do something like:

Œwcall 'W_Ini' '[call]BC_SendMessage=L(HW,U,U,*C) ALIAS SendMessageA'

 

I know that I'm not overwriting anyone elses definition and, if I want, I can delete BC_SendMessage when my application exits (but I normally wouldn't - why bother).  I can define items in any section (call, type, constant), and just give them my own names.

 

This does not handle the case where the INI file is read-only, but I find that an uncommon enough scenario that I haven't worried about it.  It handles shared INI files only if you don't delete them on exit.

     

davin.church
Temporary []WCALL definition
Posted: Tuesday, May 25, 2004 2:14 PM (EST)

That's a good breakdown Brian.  But how about some other situations in those categories?

 

For instance, when I write utilities I don't want them to impact a user in any unnecessary way.  End-users never know about INI/ADF files anyway, but even many programmers don't deal with them (or even know how to deal with them).  So I really don't want to be changing their files for them without permission.  Some people (including me) don't like that.

 

If I want to try out a bunch of sample code, I don't really want each program changing my INI file and cluttering it up.  Many such routines don't clean up after themselves, and I wouldn't be too good about looking for un-install routines even if they are there, especially if I didn't know it did such things in the first place.

 

Likewise, I don't want to have to require people to make INI/ADF changes to use (or distribute) my stuff.  IMO, utilities should be as invisible and easy to use (and fast) as possible.

 

As far as deleting the definitions afterwards, that can be useful in some situations, but there are still difficulties involved.  Of course it doesn't handle the read-only problem, but simply getting rid of it afterwards is often difficult.  If you're exiting the routine early (e.g. null/trivial cases, special cases, etc.), you have to add additional "delete" calls for those exits.  If the code crashes (which many sample programs do, or for improper usage you hadn't trapped for), you can't delete it afterwards.  If you use []error (especially from []elx) it also gets to be obnoxious.  And then there's the problem of using such a routine frequently -- are you going to re-write the entire INI file twice every time you call it??  That's going to slow things down tremendously (not to mention wearing out your hard drive).

 

Just preventing the disk I/O in the first place sure seems like the simplest and most effective situation to me.  Everybody's been mentioning workarounds, which is fine for now, but is it unreasonable to make a trivial change to the interpreter to avoid having to use any workarounds in the first place?

     

Michael.Shumate
Temporary []WCALL definition
Posted: Wednesday, February 23, 2005 5:56 PM (EST)

I know this is an old thread, but I just got access.

 

What about the ability to store the "special" definitions in a variable?

 

Where the WCALL would be something like:

 

x []WCALL 'fn....'

 

where x is the variable in which the definitions are stored.

 

Currently []WCALL doesn't have a left arg, so this doesn't impact current syntax.

 

Just a thought. 

     

davin.church
Temporary []WCALL definition
Posted: Wednesday, February 23, 2005 9:06 PM (EST)
That sounds like a reasonable approach to me.

     



APL2000 Official Web Site

The influence of each human being on others in this life is a kind of immortality.
--- John Quincy Adams

APLDN Home   |    |  Events   |  Trainings   |  APL Books   |  APLDN Links   |    |  Discussion Groups   |    |  Downloads   |  Articles   |  Library   |  Learning Tools   |  APLDN User IO   |  APL2000.com   |