From: John DeSoi
Subject: foreign function help on Windows
Date: 
Message-ID: <160120020133558100%jdesoi@planetc.com>
Greetings,

I'm trying to provide a (free) Lisp interface for the Valentina
relational database (http://www.paradigmasoft.com/). I'm starting with
a shared library version that only has one entry point (based on the
HyperCard XCMD model - everything is passed as a string). 

I have this working for Macintosh Common Lisp, but I can't seem to get
the foreign interface right for anything on Windows. I have tried both
LispWorks and Corman Lisp. If you know how to write this for either
environment, please let me know. Contributions for any other Lisp
environment would also be very much appreciated.

John DeSoi, Ph.D.



Command data structure and the Dispatch function I want to call:

   typedef struct {
      short                      paramCount;
      Handle                     params[16];
      Handle                     returnValue;
      Boolean                 passFlag;
      char                    filler1;
      void*                   entryPoint;
      short                      request;
      short                      result;
      long                    inArgs[8];
      long                    outArgs[4];
   } XCmd, *XCmdPtr;
   

#ifdef VXCMD_DLL
   #define VXCMD_EXPORT __declspec(dllexport) 
#else
   #define VXCMD_EXPORT 
#endif

#ifdef __cplusplus
extern "C" {
#endif

   VXCMD_EXPORT void Dispatch( XCmdPtr inParamPtr );

#ifdef __cplusplus
}
#endif


Example of calling Dispatch in C:

void Valentina(char *args[], int nargs, char **retstring, Bool *pass,
Bool *error) 
{
    XCmdBlock p;
    
    for( int i = 0; i < 16; ++i )
    {
        p.params[i] = (i < nargs) ? (args + i) : NULL;
            // make like MacOS handle :-)
    }
    
    p.paramCount     = (short) nargs;
    p.returnValue     = NULL;
    
    // Dispatch the request to the appropriate function
    Dispatch( &p );
    

    *pass     = false;
    *error     = false;
    
    if( p.returnValue )
    {
        *retstring = (char*) p.returnValue;
    }
    else
    {
        *retstring = (char*) malloc(1);
        **retstring = 0;
    }
        
} /* Valentina */
From: Timothy M. Schaeffer
Subject: Re: foreign function help on Windows
Date: 
Message-ID: <3c4d0e2e$0$35619$272ea4a1@news.execpc.com>
"John DeSoi" <······@planetc.com> wrote in message
······························@planetc.com...
> Greetings,
>
> I'm trying to provide a (free) Lisp interface for the Valentina
> relational database (http://www.paradigmasoft.com/). I'm starting with
> a shared library version that only has one entry point (based on the
> HyperCard XCMD model - everything is passed as a string).
>
> I have this working for Macintosh Common Lisp, but I can't seem to get
> the foreign interface right for anything on Windows. I have tried both
> LispWorks and Corman Lisp. If you know how to write this for either
> environment, please let me know. Contributions for any other Lisp
> environment would also be very much appreciated.
>
> John DeSoi, Ph.D.
> ...

I am working on a lisp interface to the allegro graphics library, and have
run into the same problem.  Allegro uses many function pointers in its
arrays, and defines a lot of inline functions that are called through these
pointers.  But there is no way to call a C function through a C function
pointer in Corman Lisp, so I'm stuck.  Luckily, allegro exports external
implementations of these functions, so I can work around it for the moment.
Looking at the Corman Lisp source, it seems calling some non-exported
internal function in the FFI might work, but it would (will?) be somewhat
messy.  If I work this out, I'll try to remember to let you know.

Bons^ancon!

- TMS

P.S. I plan on offering the interface to  public domain, or LGPL, or under
allegro's terms, or whatever.  Also, I might change Lisp platforms, and
forthwith the interface to Corman Lisp will be a low priority.