FFI and Emacs

"Todd Lucas" <[email protected]> Sat, 31 May 2003 13:12:20 -0700
Newsgroups gmane.lisp.corman
Message-ID <[email protected]>
Hi,
I'm new to this group. I just started with Corman Lisp and am finding it to
be an excellent product.

I've been running it under Emacs inferior Lisp mode using Bill Clementson's
excellent initialization file. The problem I'm having is calling a foreign
function. When I do so under Emacs clconsole hangs. This question appears
very similar to one posted by Bill himself (#925). After several hours of
digging, I've found the cause.

The cause of the problem is in the C runtime DLL init code supplied with VC
6 and its interaction with the Windows API function GetFileType. You can see
the offending line in vc98\crt\src\ioinit.c(250). The problem is that during
_DllMainCRTStartup the CRT is attempting to acquire the inherited stdio file
handles. It gets an apparently valid handle via GetStdHandle but then hangs
in (I'm assuming) an infinite loop in GetFileType.

The example supplied with Corman Lisp (testdll.dll) works, it appears, since
it's linking to msvcrt.dll.  However, linking to any of the static libraries
or the multithreaded debug DLL (msvcrtd.dll) causes the problem to appear.
I'm not sure why the problem occurs in the debug multithreaded DLL but not
in the non-debug multithreaded DLL.

I've attempted various fixes such as modifying Emacs' cmdproxy.c startup
stub, passing the handles and inherit flag in various combinations, but to
no effect. The solution I found is a workaround that requires replacing the
standard handles in a "raw" DllMain, which must be fixed-up to the
_pRawDllMain pointer exported from the CRT initialization code. This routine
gets called prior to the internal CRT DllMain (_CRT_INIT) and thus can't
call any CRT functions. You can see this in vc98\crt\src\dllcrt0.c. To
implement the workaround, just add the following code to your project. Your
DLL should then be callable when you link to any of the six CRT types except
"Debug Multithreaded DLL".

The product versions I'm using are: Corman Lisp 2.01 (with the latest
patches), Windows XP SP1, Emacs 21.2.1, and MSVC 6.0 SP5.

- Todd


extern "C" BOOL WINAPI
RawDllMain(HANDLE hModule,
           DWORD  dwReason,
           LPVOID lpReserved)
{
    static HANDLE s_hFile;

    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        s_hFile = CreateFile("nul:", GENERIC_READ, FILE_SHARE_READ,
                           0, OPEN_EXISTING, 0, 0);
        if (INVALID_HANDLE_VALUE != s_hFile)
        {
            if (SetStdHandle(STD_INPUT_HANDLE,  s_hFile) &&
                SetStdHandle(STD_OUTPUT_HANDLE, s_hFile) &&
                SetStdHandle(STD_ERROR_HANDLE,  s_hFile))
            {
                return TRUE;
            }
        }
        return FALSE;

    case DLL_PROCESS_DETACH:
        if (INVALID_HANDLE_VALUE != s_hFile)
        {
            CloseHandle(s_hFile);
            s_hFile = INVALID_HANDLE_VALUE;
        }
        break;

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

extern "C" BOOL (WINAPI *_pRawDllMain)(HANDLE, DWORD, LPVOID) = &RawDllMain;


------------------------ Yahoo! Groups Sponsor ---------------------~-->
Get A Free Psychic Reading! Your Online Answer To Life's Important Questions.
http://us.click.yahoo.com/Lj3uPC/Me7FAA/ySSFAA/SyjtlB/TM
---------------------------------------------------------------------~->

To unsubscribe from this group, send an email to:
[email protected]

 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/