Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compile C++/CLI code for Silverlight?

I have a C++/CLI library that I would like to use in a Silverlight application. It is supposed to be possible to write code for Silverlight in any .NET language, but so far I've only worked out how to compile C#. Silverlight does not seem to be able to use DLLs compiled for .NET.

I'm using Visual Studio 2010 and Silverlight 4. The only new projects available for Silverlight are C# projects. Porting the code to C# is not a practical option.

How do I compile C++/CLI code for Silverlight?

like image 335
richj Avatar asked Dec 10 '22 12:12

richj


2 Answers

I think I may have gotten a VS2010 C++/CLI class library project to build with references to (only) Silverlight assemblies.

Update

Ok, it is possible. But it is not nice.

First, you must convince the C++ compiler to NOT load the .NET Framework, using an undocumented compiler switch. But that's not the worst part.

  • Set your C++/CLI project "Common Language Runtime Support" to /clr:safe
  • Next, under References, remove all references.
  • Next, in the C++/CLI project properties, under C++ > Command Line, enter /d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
  • Now, save the project and exit Visual Studio. Open the .vcxproj in a text editor, and change the framework version setting. You want it to be the same as a C# Silverlight project:

    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>

  • Now, reopen Visual Studio, and build the project. You'll get an error because the compiler auto-generated a file with #using<mscorlib> and the search path finds the .NET Framework version first.

    Silverlight,Version=v4.0.AssemblyAttributes.cpp(1): fatal error C1197: cannot reference 'c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll' as the program has already referenced 'c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll'

  • Double-click the error to open the auto-generated file. Replace the path-less reference with e.g. (here's where you put your references, not in the project properties)

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.Core.dll>

  • Luckily, the compiler leaves your changes in-place. So you should be good as long as no one cleans your temp directory.

  • Building should now succeed.

Then, you need to go add the DLL created by the C++/CLI project to your Silverlight application. Note that you can't set up a project reference, because VS2010 still isn't convinced that the C++/CLI is a Silverlight project. So you'll have to browse and add the reference as an assembly file. (And it won't automatically switch between Debug and Release to match the Silverlight application).

Final Notes

I got it to run an empty Silverlight application in Debug mode and stop at a breakpoint in the middle of C++/CLI code. Also the C++/CLI code successfully returned a value to C# and the local variable in C# received the correct value. So I guess it's working.

I went through a bunch more steps trying to make this work, but I don't think they affected the outcome. If you run into errors, though, let me know and I'll try to figure out what I omitted from this answer.

like image 124
Ben Voigt Avatar answered Jan 19 '23 11:01

Ben Voigt


Ben Voigt, thanks for this, it worked for me too.

Also, if your C++ code does anything that is specific to the C++ language (i.e. not entirely IL portable) like using stack semantics for an array, you'll get the following error:

could not find assembly 'Microsoft.VisualC.dll' etc.

If you recompile with the full .NET Framework and then dump the IL code, you'll find references to "''.$ArrayType$$$BY06$$CB_W modopt" or something similar. This tells you where to change the code.

I found that after I installed the Silverlight SDK and it got added to "\Program Files(x86)\Reference Assemblies" I did not have to go through all of Ben Voigt's steps, just changing the project file was enough.

Another note, you can also use:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

if you want to target Windows Phone (install the SDK first).

like image 33
Don Fehr Avatar answered Jan 19 '23 13:01

Don Fehr