Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lisp <--> .NET interoperability #10

Open
Lovesan opened this issue Oct 21, 2011 · 2 comments
Open

Lisp <--> .NET interoperability #10

Lovesan opened this issue Oct 21, 2011 · 2 comments

Comments

@Lovesan
Copy link

Lovesan commented Oct 21, 2011

Hello there.

I've recently figured out that SBCL and .NET runtimes, while working in one process, are not particularly fond of each other, and i'm interested if there's anything anyone can do about that.

Consider the following code (C++/CLI)

/*
 * set LIBPATH=%LIBPATH%%windir%\Microsoft.NET\Framework\v4.0.30319\WPF;
 * cl /EHac /clr /TP /LD Window.cpp
 */
#using <System.dll>
#using <WindowsBase.dll>
#using <PresentationCore.dll>
#using <PresentationFramework.dll>

#include <vcclr.h>

extern "C" __declspec(dllexport) int _stdcall OpenWindow()
{
    try
    {        
        gcroot<System::Windows::Window ^> window
            = gcnew System::Windows::Window;
        window->ShowDialog();
    } catch(System::Exception ^ e)
    {
        System::Console::Error->WriteLine(e);
        return 0;
    }
    return 1;
}

Here's an example of usage of this function for SBCL:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-alien:load-shared-object "ole32.dll")
  (sb-alien:load-shared-object "Window.dll"))

(sb-alien:define-alien-routine
    ("CoInitializeEx" %co-initialize-ex)
    (sb-alien:signed 32)
  (reserved sb-sys:system-area-pointer)
  (mode (sb-alien:unsigned 32)))

(sb-alien:define-alien-routine
    ("CoUninitialize" %co-uninitialize)
    (sb-alien:signed 32))

(sb-alien:define-alien-routine
    ("_OpenWindow@0" %open-window)
    (sb-alien:signed 32))

(defun make-com-thread (function &key (mode :sta))
  (let ((function (lambda ()
                    (%co-initialize-ex
                      (sb-sys:int-sap 0)
                      (ecase mode
                        (:sta 2)
                        (:mta 0)))
                    (unwind-protect
                        (funcall function)
                      (%co-uninitialize)))))
    (sb-thread:make-thread function)))

(defun open-window (&optional new-thread)
  (if new-thread
    (make-com-thread
        (lambda () (%open-window))
      :mode :sta)
    (progn (unless (zerop (%co-initialize-ex (sb-sys:int-sap 0) 2))
             (error "Unable to initialize COM STA"))
           (%open-window)
           (%co-uninitialize))))

While this function(OpenWindow) works perfectly when called from either C, unmanaged C++ or .NET, when called from lisp, it causes .NET runtime(and consequently, entire lisp process) to crash with ''Process terminated due to StackOverflowException" error message.

I suppose the reason of crashes is somehow related to cooperation(or rather, contention) of lisp and .NET garbage collectors in STA environment because:

  • When this function is called from MTA, it causes no crashes(it catches InvalidOperationException, complains about invalid apartment state to stderr an quits).
  • When this function is modified to simply create a window, but not to show it, there is no crash until lisp garbage collector is run(until you call sb-ext:gc, for example)

I've also tried calling this function from Clozure CL. Again, it doesn't work, but instead of simply terminating the process, CCL runtime enters low-level debugger and complains about an exception on foreign stack.

Although resolving this issue is not a matter of urgent need, it would allow better integration of SBCL and Windows platform by opening .NET BCL and libraries for lisp.

@akovalenko
Copy link
Owner

Point taken. It would be easier for me to get my hands on it if you shared the DLL, so I won't need a complete .NET development environment.

@Lovesan
Copy link
Author

Lovesan commented Oct 21, 2011

https://github.com/downloads/Lovesan/doors/Window.zip

btw, SBCL version i'm currently using is "1.0.52.1.mswinmt.969-6acb698", and .NET runtime i'm talking about is "4.0.30319" (the latest version, for this moment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants