如何为Silverlight编译C ++ / CLI代码?

时间:2010-11-20 10:59:11

标签: silverlight visual-studio-2010 compiler-construction silverlight-4.0 c++-cli

我有一个C ++ / CLI库,我想在Silverlight应用程序中使用它。应该可以在任何.NET语言中为Silverlight编写代码,但到目前为止我只研究了如何编译C#。 Silverlight似乎无法使用为.NET编译的DLL。

我正在使用Visual Studio 2010和Silverlight 4. Silverlight唯一可用的新项目是C#项目。将代码移植到C#不是一个实用的选择。

如何为Silverlight编译C ++ / CLI代码?

5 个答案:

答案 0 :(得分:10)

我想我可能已经获得了一个VS2010 C ++ / CLI类库项目来构建,并引用了(仅限)Silverlight程序集。

更新

好的, 可能。但它不是很好

首先,您必须使用未记录的编译器开关说服C ++编译器不加载.NET Framework。但这不是最糟糕的部分。

  • 将您的C ++ / CLI项目“公共语言运行时支持”设置为/clr:safe
  • 接下来,在参考文献下,删除所有引用。
  • 接下来,在C ++ / CLI项目属性中,在C ++>下;命令行,输入/d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
  • 现在,保存项目并退出Visual Studio。在文本编辑器中打开.vcxproj,然后更改框架版本设置。您希望它与C#Silverlight项目相同:

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

  • 现在,重新打开Visual Studio,然后构建项目。您将收到错误,因为编译器使用#using<mscorlib>自动生成文件,并且搜索路径首先找到.NET Framework版本。

    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'

  • 双击错误以打开自动生成的文件。用例如替换无路径引用(这里是您放置引用的地方,而不是项目属性)

    #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>

  • 幸运的是,编译器会将您的更改保留在原位。只要没有人清理你的临时目录,你就应该很好。

  • 建筑现在应该成功。

然后,您需要将C ++ / CLI项目创建的DLL添加到Silverlight应用程序中。请注意,您无法设置项目引用,因为VS2010仍然不相信C ++ / CLI是Silverlight项目。因此,您必须浏览并将引用添加为程序集文件。 (并且它不会在Debug和Release之间自动切换以匹配Silverlight应用程序。)

最终笔记

我让它在调试模式下运行一个空的Silverlight应用程序,并在C ++ / CLI代码中间的断点处停止。此外,C ++ / CLI代码成功将值返回给C#,C#中的局部变量收到了正确的值。所以我猜它正在发挥作用。

我经历了一些尝试使这项工作更多的步骤,但我认为它们不会影响结果。但是,如果你遇到错误,请告诉我,我会试着弄明白我从这个答案中省略了什么。

答案 1 :(得分:2)

Ben Voigt,谢谢你,它也适合我。

此外,如果您的C ++代码执行特定于C ++语言的任何操作(即不完全是IL可移植的),例如对数组使用堆栈语义,您将收到以下错误:

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

如果使用完整的.NET Framework重新编译然后转储IL代码,您将找到对“''。$ ArrayType $$$ BY06 $$ CB_W modopt”或类似内容的引用。这告诉您在哪里更改代码。

我发现在安装了Silverlight SDK并将其添加到“\ Program Files(x86)\ Reference Assemblies”之后,我没有必要完成Ben Voigt的所有步骤,只需更改项目文件即可。< / p>

另外注意,你也可以使用:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

如果您要定位Windows Phone(首先安装SDK)。

答案 2 :(得分:1)

由于安全问题,Silverlight不支持本机C ++库,也不支持任何P / Invoke方案。如果您的库是纯.Net,您可以使用ILDASM对其进行反编译,并使用ILASM重新编译Silverlight。

答案 3 :(得分:1)

Silverlight不是像.NET这样与操作系统紧密集成的强大开发平台。首先,silverlight应该可以在任何操作系统上运行,因此Silverlight中无法选择Native API。

Silverlight也不完全支持MSIL,因此在IL级编译和重组时存在很多问题。

您能详细说明您拥有哪种C ++ / CLI代码吗?大多数Rich Internet应用程序(Silverlight的目标)不包含任何高强度计算,而是简单的HTML + JS替代方案。对于强大的图形,您可以使用Silverlight的PixelShadder支持。

Reflector

你可以做的是, 将您的C ++ / CLI编译为常规.NET DLL,使用Reflector从您的dll中反汇编并生成C#源代码,它可能不完美,但您将把大部分逻辑转换回C#。

答案 4 :(得分:0)

我能够使用Ben Voigt的解决方案来处理Visual Studio 2013中的一些细微变化 这是我做的不同。

  • 卸载要引用它的silverlight项目。右键单击并选择编辑project.csproj
  • 复制目标框架设置。对我来说这是

    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
    
  • 对于编译器切换/d1clr:nomscorlib这对我不起作用。此外,对于Silverlight的mscorlib引用也自动添加到编译输出中,而不在命令行选项中指定它。这就是我如何解决它。

  • Just Deompile

  • 中打开项目
  • 加载程序集编辑器插件

  • 将树导航到参考

  • 从reflexil菜单中删除对非silverlight mscorlib的引用。

  • 右键单击树的顶层以进行装配,并保存在reflexil菜单下。

我没有测试过所有的功能,但到目前为止我测试的功能都按预期工作了。

谢谢Ben,你的帖子为我节省了很多时间。我以为我将不得不移植我的库:)