[IronPython] ctypes on Mono

Tristan Zajonc tristanz at gmail.com
Thu Jun 10 02:03:46 CEST 2010


I looked into the ctypes on mono problem a bit (MONO_LOG_LEVEL=debug mono
ipy.exe is helpful here).  There seem to be three issues:

1) libdl.so is libdl.dylib on OSX and there is no dllmap that does this
automatically on Mono.  It checks for libdl.so.dylib and a few other places
but not libdl.dylib.  This can be fixed by creating a symbolic link or
changing the DLLImport to libdl without the ".so".  Unfortunately the latter
approach breaks breaks linux support.  So I just created this symlink by
hand, which is not ideal.

2) On linux, it seems that RTLD_NOW (2) should be passed to the dlopen call.
(See http://www.mail-archive.com/mono-list@lists.ximian.com/msg30407.html).
 Without this import ctypes works on OSX but not linux, with it things seem
to work on both platforms.

3) LocalAlloc needs a posix equivalent.  I added a calloc(1, size), which
seemed to do the trick.  I'm not expert here, I assume some of the other
public methods should be ported too?

With these changes basic libc calls, like abs(), work on windows, osx, and
linux. Lots stuff doesn't work. Printf gives one character everywhere and
segfaults on linux, but this seems to be the general state of ctypes support
even on Windows.  Unfortunately fcntl through ctypes also doesn't seem to
work, which is why I was looking into ctypes to start with.

Below are my changes to NativeFunctions.cs, which are a partial solution at
best.

Tristan

---

        // unix entry points, VM needs to map the filenames.
        [DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi)]
        private static extern IntPtr dlopen([In] string filename, [In] int
flags);

        [DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi)]
        private static extern IntPtr dlsym([In] IntPtr handle, [In] string
symbol);

        [DllImport("libdl.so")]
        private static extern IntPtr calloc(uint nelem, IntPtr size);

        // Required for Unix not OSX.
        private const int RTLD_NOW = 2;

        public static IntPtr LoadDLL(string filename, int flags) {
            if (Environment.OSVersion.Platform == PlatformID.Unix ||
                Environment.OSVersion.Platform == PlatformID.MacOSX) {
                return dlopen(filename, RTLD_NOW);
            }
            return LoadLibrary(filename);
        }

        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
        public static IntPtr Calloc(IntPtr size) {
            if (Environment.OSVersion.Platform == PlatformID.Unix ||
                 Environment.OSVersion.Platform == PlatformID.MacOSX) {
                     return calloc(1, size);
            }
            return LocalAlloc(LMEM_ZEROINIT, size);
        }

---



On Tue, Jun 1, 2010 at 3:13 PM, Tristan Zajonc <tristanz at gmail.com> wrote:

> Both on OSX and Ubuntu it appears to fail on a call to PyDLL(None).  The
> problematic call is from the block:
>
> if _os.name in ("nt", "ce"):
>     pythonapi = PyDLL("python dll", None, _sys.dllhandle)
> elif _sys.platform == "cygwin":
>     pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
> else:
>     print "DEBUG: NOT NT/CE OR CYGWIN."
>     pythonapi = PyDLL(None)
>
> It goes to CDLL base class and dies exactly here:
>
> if handle is None:
>     print "HANDLE: " + str(self._name) + str(mode)  #prints None0
>     self._handle = _dlopen(self._name, mode)
>     print "AFTER DLOPEN. DOESN'T PRINT."
>
> Hope this helps.
>
> Tristan
>
> On Tue, Jun 1, 2010 at 1:34 PM, Dino Viehland <dinov at microsoft.com> wrote:
>
>>  Any chance you can put a print in any calls to dlopen in
>> ctypes\__init__.py and see what we’re trying to load?
>>
>>
>>
>> *From:* users-bounces at lists.ironpython.com [mailto:
>> users-bounces at lists.ironpython.com] *On Behalf Of *Tristan Zajonc
>> *Sent:* Sunday, May 30, 2010 3:57 PM
>> *To:* Discussion of IronPython
>> *Subject:* Re: [IronPython] ctypes on Mono
>>
>>
>>
>> (I'll look into OSX issue, although am happy to hear a solution from other
>> users)
>>
>>
>>
>> I'm not sure why I don't get line numbers.  If I pass -XExceptionDetail, I
>> don't get much more:
>>
>>
>>
>> tristanz at aontic1:~$ ipy -X:ExceptionDetail
>>
>> IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433
>>
>> Type "help", "copyright", "credits" or "license" for more information.
>>
>> >>> import ctypes
>>
>> cannot load library
>>
>> LoadLibrary at offset 0 in file:line:column <filename unknown>:0:0
>>
>> dlopen at offset 0 in file:line:column <filename unknown>:0:0
>>
>> Invoke at offset 0 in file:line:column <filename unknown>:0:0
>>
>>   at IronPython.Modules.CTypes.LoadLibrary (System.String library, Int32
>> mode) [0x00000] in <filename unknown>:0
>>
>>   at IronPython.Modules.CTypes.dlopen (System.String library, Int32 mode)
>> [0x00000] in <filename unknown>:0
>>
>>   at (wrapper managed-to-native)
>> System.Reflection.MonoMethod:InternalInvoke
>> (System.Reflection.MonoMethod*,object,object[],System.Exception&)
>>
>>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags
>> invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
>> System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>>
>> OSError: IronPython.Runtime.Exceptions.OSException: cannot load library
>>
>>   at IronPython.Modules.CTypes.LoadLibrary (System.String library, Int32
>> mode) [0x00000] in <filename unknown>:0
>>
>>   at IronPython.Modules.CTypes.dlopen (System.String library, Int32 mode)
>> [0x00000] in <filename unknown>:0
>>
>>   at (wrapper managed-to-native)
>> System.Reflection.MonoMethod:InternalInvoke
>> (System.Reflection.MonoMethod*,object,object[],System.Exception&)
>>
>>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags
>> invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
>> System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>>
>>
>>
>>
>>
>> On Sun, May 30, 2010 at 6:24 PM, Dino Viehland <dinov at microsoft.com>
>> wrote:
>>
>> On OS/X I believe you need to use Mono’s DllMap feature (
>> http://www.mono-project.com/Config_DllMap) to map from the Linux library
>> name (libdl.so) to the Mac OS/X library which exports dlopen.  I actually
>> have no clue what exports it and I don’t see one listed over here:
>> http://gemma.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/dlopen.3.htmlso hopefully someone else on the list knows.
>>
>>
>>
>> It looks like on Linux the –X:ExceptionDetail command line option is being
>> passed which is preventing the stack trace from having any line number
>> information - or maybe the stack trace is cut off?  Either way it’d be
>> useful to see the line number which is calling dlopen to understand what
>> library we are failing to load.  My guess would be that it’s trying to load
>> the Python library but I’d think that would work fine (it looks like we pass
>> in a null path in that case which should be alright for dlopen).
>>
>>
>>
>>
>>
>> *From:* users-bounces at lists.ironpython.com [mailto:
>> users-bounces at lists.ironpython.com] *On Behalf Of *Tristan Zajonc
>>
>>
>> *Sent:* Saturday, May 29, 2010 3:59 PM
>> *To:* Discussion of IronPython
>>
>> *Subject:* [IronPython] ctypes on Mono
>>
>>
>>
>> I'm running the the latest IronPython 2.6.1 (.NET 2.0 version) with Mono.
>>  I cannot import ctypes.
>>
>>
>>
>> Is this behavior expected?  Any solutions?  Here are the exact results:
>>
>>
>>
>> On OSX:
>>
>> IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433
>>
>> Type "help", "copyright", "credits" or "license" for more information.
>>
>> >>> import ctypes
>>
>> Traceback (most recent call last):
>>
>> SystemError: libdl.so
>>
>>
>>
>> On Ubuntu (using trunk Mono):
>>
>>
>>
>> IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433
>>
>> Type "help", "copyright", "credits" or "license" for more information.
>>
>> >>> import ctypes
>>
>> Traceback (most recent call last):
>>
>> OSError: IronPython.Runtime.Exceptions.OSException: cannot load library
>>
>>   at IronPython.Modules.CTypes.LoadLibrary (System.String library, Int32
>> mode) [0x00000] in <filename unknown>:0
>>
>>   at IronPython.Modules.CTypes.dlopen (System.String library, Int32 mode)
>> [0x00000] in <filename unknown>:0
>>
>>   at (wrapper managed-to-native)
>> System.Reflection.MonoMethod:InternalInvoke
>> (System.Reflection.MonoMethod*,object,object[],System.Exception&)
>>
>>   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags
>> invokeAttr, System.Reflection.Binder binder, System.Object[] parameters,
>> System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
>>
>>
>>
>>
>>
>> Best,
>>
>> Tristan
>>
>>
>> _______________________________________________
>> Users mailing list
>> Users at lists.ironpython.com
>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>
>>
>>
>> _______________________________________________
>> Users mailing list
>> Users at lists.ironpython.com
>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100609/c76e1267/attachment.html>


More information about the Ironpython-users mailing list