Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Friday, September 16, 2011

P/Invoke: Bundling native DLL:s in Silverlight 5 RC applications

One of the many interesting new features in Silverlight 5 RC is the ability for elevated trust applications (in-browser as well as out-of-browser) to access native DLL:s via P/Invoke.

Some interesting application examples are given here and here. These examples show how easy it is to access system DLL:s such as user32.dll, kernel32.dll and psapi.dll. However, the issue appears to be more complex when it comes to native DLL:s that are not automatically available on the system.

Ideally (I think), you would like to bundle the native third party DLL:s as Content in the XAP file, and the XAP file would be artificially included in the P/Invoke search path. Unfortunately, this is not the way it works today. When I bundle my third-party native DLL as Content in my Silverlight 5 RC application, and try to access one of its methods via the following declaration,

[DllImport("NativeDll")]
public static extern int add(int a, int b);


I get a discouraging DllNotFoundException. It does not help if I add the .dll extension to the file name, and I have also not been able to find the DLL by applying any of the pack URI approaches to the DLL file name.

Several people, including myself, have brought up this issue in various forums, but so far I have not seen any published solution to the problem.

Well, as we say in Sweden, "själv är bäste dräng" (which is similar to "if you want something done, do it yourself"), so here is my attempt to solve the problem. Granted, it might not be the most Elegant Solution, but at least it is A Solution.

It is important to note that this solution is applicable primarily to Silverlight 5 RC. In the best of worlds, Microsoft will fix the native DLL path issue in the RTM release of Silverlight 5, and then this solution would be superfluous. We'll see what happens in the end.

Note also that since P/Invoke is a feature requiring elevated trust, this solution is only relevant to applications running in elevated trust (in- or out-of-browser).


In short, the solution is to bundle the native third party DLL:s as resource files in the Silverlight 5 RC application, and when the application is started copy these DLL:s to a local directory and add the directory to the system path during the execution of the Silverlight application.

In more details, here is how it can be done:

Add each native third party DLL as an existing item to the root folder or, even more preferably, to an assets sub-folder in the Silverlight 5 RC application project.


In the File Properties window, set Build Action to Resource and Copy to Output Directory to Copy if newer.


The DLL copying and PATH environment variable setting of course requires some additional code. Fortunately :-) I have created a static utility class for this purpose. The class is named NativeDllHelper and can be found it is entirety here. Download and add this file to your Silverlight 5 RC application project.

Next, go to the App.xaml.cs or equivalent file. Add the following using statement.

using Cureos.Utility;

In the Application_Startup (or equivalent) event handler, add the following method call to the first line of the event handler.

NativeDllHelper.SetupNativeDllFolder("relpath/dllname.dll", ...);

where relpath is the path relative to the project root folder where the native DLL:s are located, and dllname is the file name of the DLL. Specify all DLL:s to be copied in one argument list; the SetupNativeDllFolder method should only be called once at start-up to avoid adding duplicate entries of the local DLL directory to the system path.

The native DLL files are copied to a My Documents sub-folder Silverlight\Native. If you prefer a different folder for the DLL:s, edit the static constructor of the NativeDllHelper class.

Here is an example call of SetupNativeDllFolder, copying one file NativeDll.dll located in the Assets sub-folder of the Silverlight 5 RC application project.

NativeDllHelper.SetupNativeDllFolder("Assets/NativeDll.dll");

Having performed these steps, no user intervention is required when running the application, the native methods in the third party DLL:s can simply be invoked using only the file name of the DLL:

[DllImport("NativeDll")]
public static extern int add(int a, int b);


A complete example SL 5 RC application utilizing this functionality can be downloaded from here. Note that it contains a C(++) project for creating the example native DLL.
If you try out the application and get build errors due to copy prevention the first time, building a second time should do the trick. You might also need to manually set the start page of the Web project to the .aspx file.


The application itself is very simple; there is this button

with the following click event handler associated to it:

private void Button_Click(object sender, RoutedEventArgs e)
{
  button.Content = add(5, 7);
}

The add method is a native method, as declared above. Clicking the button leaves us with the following satisfying button update:

And that is basically all that there is to it. The utility method for copying DLL:s from the application resources can most certainly be further improved, for example by more efficiently handling DLL:s already existing locally. With the current implementation, any existing DLL:s are automatically overwritten. All improvement suggestions as well as reports of successes or failures are highly appreciated.

Monday, September 5, 2011

csipopt on Silverlight: almost there!

As mentioned in a recent post, it is possible to enable unsafe code support in the release candidate of Silverlight 5 for out-of-browser (OOB) applications in elevated-trust mode. Together with the introduction of P/Invoke support in Silverlight 5, it would thereby in principle be possible to also use my csipopt .NET interface to the IPOPT optimizer in Silverlight.

I have now tested to build and run csipopt on Silverlight 5 RC, and it almost works:
  • The code successfully builds, provided the <AllowUnsafeBlocks> tag is manually set to true in the .csproj file.
  • If I bundle the native IPOPT DLL:s as content or resources in the XAP file, I get a DllNotFoundException. At this point I do not know if this is a bug or by design. For now, it works to place the native IPOPT DLL:s in a directory that is included in the system path.
  • When I run my csipopt calling application in OOB elevated-trust mode, I eventually get a SecurityException: An error relating to security occurred
The exception occurs when trying to access an UnmanagedFunctionPointerAttribute in a call to an imported function from the native DLL. It remains to find out whether this restriction will persist into the final release of Silverlight 5. According to the API documentation, the UnmanagedFunctionPointerAttribute is not intended for regular user code in Silverlight. This writing might not be entirely up-to-date, but realistically, I think the restriction will be there at least in Silverlight 5. After all, I am pushing the limits here, using P/Invoke and unsafe code at the same time.

So, bets are I have to wait for Silverlight 6 to employ csipopt in my Silverlight applications.

DICOM on the phone!

I received an e-mail the other day from Pantelis Georgiadis. He wrote that he had forked my mdcm fork and that he is now developing a Windows Phone 7.1 ("Mango") class library based on my Silverlight mdcm efforts.

It is really great to see that Colby Dillion's, and more recently my, work on this C# DICOM library is now proliferating into the phone. It will be very interesting to follow Pantelis's work and see what kind of applications will come out of his efforts.

Friday, September 2, 2011

Unsafe support in Silverlight 5?

Silverlight 5 Release Candidate is available for download since yesterday. Interestingly enough, the RC supports P/Invoke for calling native functions. If only Silverlight could also support unsafe code, it would maybe be possible to use csipopt, my .NET interface to the IPOPT optimizer, from Silverlight...

After downloading and installing the Silverlight 5 RC Tools for VS 2010 SP1, I created a simple Silverlight 5 application project. Discouragingly, the Unsafe checkbox in the project settings is still disabled:


But at least the checkbox is there... Maybe I can manually edit the project file. In a regular C# project, unsafe support is indicated within each configuration/platform PropertyGroup using the following tag:

    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

So, let's insert the same specification in the Silverlight project file and reload the project. The unsafe checkbox is still disabled, but lo and behold, the checkbox is checked!


Next, let's see if I can add some unsafe code and build it. First, I create a button with the instructive text "Click me!". I add the following event handler for the button Click event:

unsafe private void UnsafeTestButton_Click(
    object sender, RoutedEventArgs e)
{
    int i = 5;
    SquarePtrParam(&i);
    UnsafeTestButton.Content = i;
}


The event handler in turn calls a simple unsafe method that dereferences an integer pointer and squares it:

unsafe static void SquarePtrParam(int* p)
{
    *p *= *p;
}


After calling the SquarePtrParam method, the click event handler should update the button content to the value of the squared integer. (If the code looks familiar I have copied it from MSDN:s C# reference section on unsafe.)

When I now build this "unsafe" Silverlight application, I get the encouraging prompt "Rebuild All succeeeded"!

Next question is, can the "unsafe" Silverlight application also be executed? It turns out that when I run it in-browser and click the button, I encounter a VerificationException, "Operation could destabilize the runtime", regardless of whether I run in normal or elevated trust. When I run out-of-browser, I get the same exception when running in normal trust, but when running out-of-browser and elevated trust, I can successfully go from here:

to here:


So the conclusion is that Silverlight 5 RC does provide hidden-away support for unsafe code. At this point it only seems to be executable out-of-browser in elevated trust. It will be interesting to see to what extent the unsafe support will be exposed in the official Silverlight 5 release.

Sidenote: I was also able to build the "unsafe" project with Silverlight 4. However, in this case I encountered the VerificationException in out-of-browser elevated-trust mode as well.


Thursday, August 18, 2011

Finally! WPF support in mdcm!

As I have mentioned in several recent blog posts, I have forked Colby Dillion's excellent C# DICOM class library mdcm and implemented a Silverlight DICOM class library largely based on the original mdcm code.

When dealing with Silverlight imaging support, it was apparent that it would be very easy to also make a WPF port of the mdcm class library.

Well, consider it done!

As of today, I have uploaded an update of mdcm to the Github repository, containing a complete .NET 4 class library Wpf.Dicom where DICOM images are rendered using WPF rather than Windows Forms.

Apart from imaging, the Wpf.Dicom project provides the same functionality as the original Dicom and Dicom.Linq projects combined. There are parts of the implemented imaging code for WPF that still remains untested, more specifically image rotation and flipping as well as multilayered images. I plan to test this specific functionality as soon as possible to verify that the WPF implementation is indeed fully functional.

The Dicom.Codec and Dicom.Codec64 projects have previously referenced the original Dicom project. To enable full codec support in WPF, I have updated the codec projects to instead reference Wpf.Dicom, and at the same time I have excluded the Windows Forms-based project Dicom and associated applications from the Visual Studio solution. This is of course an easy thing to change back, if anyone so wishes.

Please feel free to download and use the source code from Github. Comments and improvement suggestions are more than welcome. Do not hesitate to report issues under the Issues tab in the Github repository.

Thursday, June 9, 2011

Physical unit converter for the phone!

It was all too tempting, I had to try it out to see if I could make it work.

My first attempts with the Windows Phone 7 development tools were disappointing, but with WP 7.1 beta ("Mango") I have managed to build and use the csunits class library without problems.

And this is what the Physical Unit Converter looks like in the Windows Phone emulator!


I have previously created a Silverlight unit converter, which can also be found in the csunits GitHub repository. The Windows Phone Unit Converter uses practically the same code, except that the ComboBoxes for selecting quantity and units have been replaced with the ListPicker control from the WP7 toolkit.

It should be noted that the csunits class library compiled already under WP7, but some of the type reflection methods were not implemented, leading to errors when trying to identify the quantities of the library. This functionality has been a prerequisite for automatically loading the full set of quantities in the unit converter applications. Luckily, the required type reflection methods are apparently implemented in "Mango".

This has primarily been a "proof-of-concept" exercise, simply to explore the possibility of developing for the Windows Phone platform. The WP Unit Converter is definitely not in a "production state" right now :-)

I have for the time being ignored some rough edges in the application. In particular, the quantity list picker does not properly display the actual quantities in selection mode. The problem does not apply to the unit list picker controls, so I am fairly confident that the issue with the quantity list picker can be fairly easily solved.

One might ask whether these efforts are easily transferable to iPhone and Android phones as well? In principle I believe the csunits class library would be possible to build also using MonoTouch and Mono for Android, and from there it should be fairly easy to design user interfaces specific for each platform. But I'll leave this question open for now...

Monday, May 2, 2011

Image codec support in Silverlight mdcm

In my Silverlight adaptation of the mdcm DICOM class library, image codec support is only barely existing. The only fully supported codec is the RLE (Run Length Encoding) format, which is also provided as a fully .NET managed implementation in the main mdcm library.

There are a number of image files in various compression formats available for testing here. I have used these images to verify that RLE compressed files can indeed be decoded by the Silverlight mdcm library.

I have also attempted to implement JPEG codec support in the Silverlight library, but I have not yet been successful. Since I am limited to fully .NET managed implementations of JPEG encoding and decoding, there are only very few open-source alternatives available.

I have thus far only identified the following two open-source alternatives:
The former is a codec library developed practically from scratch, whereas the latter library is a C# adaptation of the LibJpeg library originally developed by the Independent JPEG Group. Neither of the above implementations appear to support images with precision larger than 8 bits. More often than not, the precision of DICOM images is 12 bits, so neither FJCore nor LibJpeg.Net seem to be capable of providing sufficient JPEG codec support in the DICOM context at this stage.

As a sidenote, Leadtools provide codecs for JPEG and several other image formats in its DICOM Silverlight SDK. This SDK however comes at a price...

Wednesday, April 13, 2011

Networking with Silverlight mdcm

As recently announced, I am adapting the C# DICOM library mdcm to Silverlight. Due to the compactness and security limitations of Silverlight, I have had to make several workarounds. However, I have now reached a stage where a large degree of the original library's functionality is in place. The only large part missing now is codec handling, which is highly dependent upon native support libraries in the original mdcm library.

Most recently, I have included network support in the Silverlight library. The client functionality is definitely in place; with the latest commit in the Github repository there is a working example of a storage SCU (service class user).

There are a few restrictions: Silverlight only supports the TCP protocol; there is currently no support for TLS or SSL. The only available port range is 4502-4534, and the port access has to be granted through a separate policy access server. As far as I have been able to find out, the server that the Silverlight client application is communicating with also has to be located on the same system. The supported DNS name of the computer should be obtained as follows:

string DnsHostName = Application.Current.Host.Source.DnsSafeHost;

(I should state that I have not yet learned all the windings of the Silverlight network support, so there may be more flexibility to this than I yet know.)

To test the functionality, I created a new Silverlight hosting web application in my mdcm fork at Github, denoted SL.DicomToXml.Web. When running this web application via Visual Studio, it is possible to open DICOM files on the regular file system. The DICOM file dump is displayed on screen, together with the contained image if any.

In the background, the application is also trying to send the DICOM object to a storage SCP server on port 4502. For this to work, a storage SCP application has to be running on the same computer (I used the storescp application from the OFFIS DCMTK library).

Furthermore, an access policy server has to be running, granting the Silverlight application access to ports 4502 through 4534. Based on code that I obtained from Stackoverflow user luke here, I also included a very simple policy server application, SilverlightPolicyServer, in the mdcm tree. Before any DICOM object sending can take place, the policy server must also be running; double-click the executable or start it from the command prompt.

Getting this to work in Silverlight was a little bit of a challenge. In particular, the Socket class in Silverlight is extremely stripped compared to its vanilla .NET counterpart. The regular mdcm library also makes extensive use of the NetworkStream class for sending and receiving network data. NetworkStream is not included at all in the core Silverlight library. Fortunately Alexander Wieser has developed a replacement in his Crystalbyte Networking project at Codeplex, and this support class was easily included in the Silverlight mdcm library.

While discussing the workarounds I have had to take in the Silverlight mdcm library, I should also mention that file access has been limited to the isolated storage assigned per user and application. This means that DICOM file access is limited to this isolated storage, and it is only practically available when running the Silverlight application. To access files on the regular file system, the most efficient solution is probably to open the file stream directly through an open-file dialog, pretty much like it is done in the demo application.

Monday, April 11, 2011

Silverlight and a converter for multiple values

Once again I have hit an annoying limitation in Silverlight, and once again the problem has been recognized and mitigated by other developers...

In XAML databinding in WPF, it is possible to do simultaneous data binding conversion for multiple values using the IMultiValueConverter interface. In the Silverlight core libraries there is however only support for single value conversion using IValueConverter.

In one example Silverlight application I developed, I wanted to compute the resulting amount in a specified physical unit, given the amount in another physical unit. A Silverlight multi-value converter would have come in handy, and gladly enough the job had already been done.

Colin Eberhardt has provided an extensive solution together with detailed usage instructions in his blog. I have applied Colin's implementation and it works flawlessly.

Apparently Silverlight 5 Beta is due at the upcoming MIX 2011 meeting. It will be interesting to see whether multi-value conversion will also be included in the SL5 libraries. If not, I still have something to fall back on, thanks to Colin.

Friday, April 8, 2011

DeflateStream in Silverlight

Another circumvented area in the Silverlight core libraries is compression and decompression of streams. The entire System.IO.Compression namespace that can be found in the regular .NET Framework is missing in Silverlight.

But of course, this limitation has been recognized. In the dotnetzip project on Codeplex, there is a Silverlight branch that among other things provide a DeflateStream replacement. This was a very welcome finding in my efforts of adapting as much as possible of the mdcm C# DICOM library to Silverlight.

My thanks go to the Codeplex user cheeso for this contribution!

WriteableBitmap extensions in Silverlight

The Silverlight WriteableBitmap class, intended for user-defined bitmap design, has very limited functionality by itself. It really only provides the Pixels property for direct modification of the editable bitmap.

Fortunately, this limitation has been recognized and mitigated by René Schule. René has initiated WriteableBitmapEx, which is a library of extension methods for the WriteableBitmap class. The entire project is open source (Microsoft Public License) and can be found on Codeplex.

I most urgently needed methods for rotation and flipping of the bitmap image, but there are also various methods for cropping, resizing, individual pixel editing, drawing shapes on the bitmap etc. All in all some very helpful extension methods for this specific need.

Thursday, April 7, 2011

Parallel operations in Silverlight

As far as I have been able to find out, Silverlight is fairly limited with respect to parallel and/or multithreaded computation support. The Parallel framework from .NET 4.0 is for example not present at all. However, it seems like the ThreadPool is a reasonable candidate for doing at least some work in parallel.

Based on the MSDN documentation for Silverlight, I have composed a very simple code snippet for separating larger computational work onto for example all available CPU cores.

int threads = Environment.ProcessorCount;
WaitHandle[] handles = new WaitHandle[threads];
for (int i = 0; i < threads; ++i)
{
handles[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
...some long-running thread-able process...
((ManualResetEvent)state).Set();
}, handles[i]);
}
WaitHandle.WaitAll(handles);

I tested the above snippet on my eight CPU core computer, and repeated the same process throughout all iterations. The above parallel approach was then 2.5 times faster than the purely sequential one. Not a very impressive result, of course. There is certainly room for improvements, hopefully I will be able to implement more impressive speed-ups in due time.

Wednesday, April 6, 2011

DICOM and WPF

I have recently taken up the effort of adapting the C# DICOM class library mdcm to Silverlight, as can be seen on the forked project website at Github.

Initially, I excluded all imaging, codec, HL7 and network functionality in order to make the library build at all in Silverlight.

Just now I have begun looking at porting the mdcm image handling to Silverlight. The mdcm library uses the .NET System.Drawing library for image handling, which is not available in Silverlight. However, I have modified the source code so that when it compiles for Silverlight, it instead uses the BitmapSource and WriteableBitmap classes from the System.Windows.Media.Imaging namespace.

The added benefit of these modifications are that they are equally applicable to WPF, i.e. it would be a simple task to switch from Windows Forms (which the original mdcm library depends upon) to WPF, given these Silverlight motivated modifications.

I have not explicitly made any WPF adaptation yet, but this is clearly worth future exploration.

UPDATE AUG 21: WPF support is now implemented! Please have a look in the Github repository and this blog post.

Friday, April 1, 2011

Advanced calculations for the web!

In my efforts to bring further functionality to the web, I have today explored the possibility of porting the versatile Meta.Numerics class library to Silverlight. Luckily enough, this was quite an easy task.

I only had to omit serialization support via the Serializable attribute, and the ADO.NET coupling of the various statistical Sample classes, otherwise the Silverlight class library built without issues.

The Meta.Numerics class library is distributed under the Microsoft Public License. I soon hope to find a suitable way for making the Silverlight library modifications public, either via Github or CodePlex.

Wednesday, March 30, 2011

DICOM and Silverlight

Since I would like to provide DICOM functionality in a Silverlight environment, I have examined whether there are any obvious libraries or tools available that would facilitate. Leadtools provide a DICOM Silverlight software development kit as a component in some of their commercial products, but so far I have not been able to identify any open source DICOM toolkit for Silverlight.

I have been using Colby Dillion's C# DICOM library mdcm for a while. This library provides all the DICOM functionality I have had the need for, but it has only been available for desktop applications until now.

However, I have started exploring whether the mdcm library can be sufficiently migrated to Silverlight. My continuous efforts can be followed here. At this stage I have made all shortcuts necessary to make the Silverlight class library build at all, and I have only included the most central parts of the original library. In due time I will fine tune the shortcuts to mimic the original library as much as possible, and I will try to add as many missing parts as I can.

It will be exciting to see if this effort can eventually result in a true open source alternative for DICOM functionality in Silverlight!