【问题标题】:How do I compile C++/CLI code for Silverlight?如何为 Silverlight 编译 C++/CLI 代码?
【发布时间】:2010-11-20 10:59:10
【问题描述】:

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

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

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

【问题讨论】:

  • 您的 C++/CLI 是否使用 /clr:safe 编译?

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


【解决方案1】:

我想我可能已经获得了一个 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# 中的局部变量接收到了正确的值。所以我想它正在工作。

我经历了更多步骤来尝试完成这项工作,但我认为它们不会影响结果。但是,如果您遇到错误,请告诉我,我会尝试找出我在此答案中遗漏的内容。

【讨论】:

  • 显然需要 Visual Web Developer 组件...我稍后会回来(很久以后)。
  • 我最终不得不在 VS2010 本身上进行功能安装,然后添加 microsoft.com/downloads/en/… ,然后在 VS 提示时添加 Developer Runtime。
  • 非常感谢您的回答。在许多小时的网络搜索中,我还没有遇到过类似的事情。
  • @richj:嗯,我自己没有发现编译器切换。请参阅opensubscriber.com/message/dotnet-cx@discuss.develop.com/… 但是该线程没有显示如何实际使用它,我不得不弄乱一堆不同的选项组合才能成功编译。当最终编译一个文件时,我遇到了自动生成文件的问题。您是否让它与您的代码一起使用?
【解决方案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 的所有步骤,只需更改项目文件就足够了。

另外说明,也可以使用:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

如果您想以 Windows Phone 为目标(先安装 SDK)。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谢谢 - 从我目前所阅读的内容来看,一些 .NET MSIL 代码可能会导致 Silverlight 运行时出现问题。可能值得一试 - 我必须检查库的单元测试覆盖率。
    【解决方案4】:

    Silverlight 不像 .NET 那样与操作系统紧密集成的强大开发平台。首先silverlight应该可以在任何操作系统上运行,所以silverlight中没有任何地方可以选择Native API。

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

    您能否详细介绍一下您拥有什么样的 C++/CLI 代码?大多数富互联网应用程序(Silverlight 的目标)不包含任何强大的计算,而是简单的 HTML+JS 替代方案。对于强大的图形,您可以使用 Silverlight 的 PixelShadder 支持。

    Reflector

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

    【讨论】:

    • C++/CLI 代码是纯 .NET 托管代码。它没有用户界面或图形;它只是一个简单的库,除了在 Silverlight 中也应该可用的系统级 DLL 之外,几乎没有依赖项。
    • @richj:“系统级 DLL”实际上是指 Silverlight 平台中包含的 .NET 程序集?
    • @Ben:是的 - 属于 Silverlight 平台的程序集。
    • 要在我的环境中工作,Reflector 必须在完全自动化的构建过程中可靠地从 C++/CLI 转换为 C#。我不能移植一次,因为该库正在积极开发中。如果我用 Ben Voigt 的方法遇到了死胡同,我会试试的。谢谢。
    【解决方案5】:

    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,您的帖子为我节省了很多时间。我在想我将不得不移植我的图书馆:)

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 2019-08-24
      • 2023-03-26
      • 1970-01-01
      • 2011-06-14
      相关资源
      最近更新 更多