Jonathan Pryor's web log
System.Diagnostics Tracing Support
As I wrote Mono's original Trace support infrastructure, I should probably get around to implementing the much improved 2.0 version. Which means I first need to understand it. Fortunately Mike Rousos is documenting how it works:
Mono.Unix Reorganization
Brad Abrams, author of the Framework Design Guidelines, recently posted his precon slides for the recent PDC.
I quickly read through it to see how it well Mono.Unix follows it. I also recently ran FxCop on Mono.Posix.dll, with many interesting results.
One major point that Abrams' slides pointed out is on page 53:
- Avoid having types designed for advanced scenarios in the same namespace as types intended for common programming tasks.
- Do ensure that each main feature area namespace contains only types that are used in the most common scenarios. Types used in advanced scenarios should be placed in subnamespaces.
This is completely different from how Mono.Unix currently operates, as it places both low-level classes such as Syscall and high-level classes such as UnixStream into the same namespace. The only difference between thw low-level and high-level is the Unix prefix present on the high-level classes. This is a problem.
It's a problem because when looking at the class view or the documentation you get lost looking at the dozens of low-level types such as AccessMode, ConfStr, and Syscall, as the high-level wrapper classes -- having a Unix prefix, will be after most of the types developers (hopefully) won't be interested in.
My solution is to separate the low-level classes into a Mono.Unix.Native namespace. The Mono.Unix namespace will be used for high-level types following CLS conventions (such as PascalCased types and methods) such as UnixFileSystemInfo, and for .NET integration classes such as UnixStream.
This change went into mono-HEAD today. All of the existing low-level Mono.Unix types have been marked [Obsolete], with messages directing users to use the appropriate Mono.Unix.Native types. Alas, some of these low-level types are used in properties or as the return types of methods in the high-level classes. These have been marked [Obsolete] for now, with a message stating that the property type or method return type will change in the next release. "Next release" in this case will be 1.1.11 or 1.2 (as I'm assuming the release of 1.1.10, which is when developers will actually see these messages if they don't follow mono-HEAD).
I'm also interested in better CLS compliance in the high-level classes. At present many of them are [CLSCompliant(false)] because they use non-CLS-compatible types such as uint or ulong. Should these be changed to CLS-compliant types? Any such changes should be done now (i.e. before 1.1.10), to allow any migration time.
Major Change to Nullable Types
Poor Martin Baulig -- Microsoft has changed the design of System.Nullable so that it's far more integrated into the runtime. This change impacts things as fundamental as the box and unbox instructions...
Frogger under Mono
DotGNU Portable.NET provides a .NET Curses wrapper for creating nifty console-based programs using the ncurses library. It is possible to run this under Mono.
Alas, the provided configure script doesn't work very well with Mono, so we need to do things manually. The following will allow you to build Portable.NET's Curses.dll ncurses wrapper and run the bundled Frogger game.
- Download and extract pnetcurses:
$ wget http://www.southern-storm.com.au/download/pnetcurses-0.0.2.tar.gz $ tar xzf pnetcurses-0.0.2.tar.gz $ cd pnetcurses-0.0.2
- Build the libcsharpncurses.so helper library. You can ignore
the warnings produced by GCC.
$ cd help $ gcc -shared -o libcsharpncurses.so *.c -lncurses input.c: In function `CursesHelpGetNextChar': input.c:69: warning: integer constant is too large for "long" type $ cd ..
- Build the Curses.dll wrapper library:
$ cd src $ mcs -t:library *.cs -out:Curses.dll Compilation succeeded $ cd ..
- Create a Curses.dll.config file so that Mono can load the
appropriate native libraries. This file should go into the same directory
as Curses.dll.
$ cd src $ cat > Curses.dll.config <<EOF <configuration> <dllmap dll="cygncurses5.dll" target="libncurses.so"/> <dllmap dll="libcsharpcurses-0-0-1.dll" target="libcsharpncurses.so"/> </configuration> EOF $ cd .. - Build the Frogger.exe demo program:
$ cd frogger $ cp ../src/Curses.dll* . $ mcs -t:exe -out:Frogger.exe -r:Curses.dll *.cs Compilation succeeded $ cd ..
- Execute Frogger.exe with Mono:
$ cd frogger $ LD_LIBRARY_PATH=`pwd`/../help mono Frogger.exe
Mono.Unix Documentation Stubs
I've just added the Mono.Unix documentation stubs. Next step is to start documenting the members, mostly by copy/pasting the current Mono.Posix documentation.
Lessons learned:
- Documentation can be out of date, especially the documentation to update existing documentation. Oops. We're supposed to use the monodocer program.
- The correct command to generate/update documentation is: monodocer -assembly:assembly-name -path:directory-name.
- The monodocer program didn't like me (it generated a NullReferenceException because of a class in the global namespace). Patch in svn-trunk.
- Documentation is an alternate view of a class library
That final point is the major point: through it, I realized that several methods in Mono.Unix which should be private were instead public. Oops. Obviously I need to document things more often...
Syndication