我有一个C ++ / CLI库,我想在Silverlight应用程序中使用它。应该可以在任何.NET语言中为Silverlight编写代码,但到目前为止我只研究了如何编译C#。 Silverlight似乎无法使用为.NET编译的DLL。
我正在使用Visual Studio 2010和Silverlight 4. Silverlight唯一可用的新项目是C#项目。将代码移植到C#不是一个实用的选择。
如何为Silverlight编译C ++ / CLI代码?
答案 0 :(得分:10)
我想我可能已经获得了一个VS2010 C ++ / CLI类库项目来构建,并引用了(仅限)Silverlight程序集。
好的, 可能。但它不是很好。
首先,您必须使用未记录的编译器开关说服C ++编译器不加载.NET Framework。但这不是最糟糕的部分。
/clr:safe
/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支持。
你可以做的是, 将您的C ++ / CLI编译为常规.NET DLL,使用Reflector从您的dll中反汇编并生成C#源代码,它可能不完美,但您将把大部分逻辑转换回C#。
答案 4 :(得分:0)
我能够使用Ben Voigt的解决方案来处理Visual Studio 2013中的一些细微变化 这是我做的不同。
复制目标框架设置。对我来说这是
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
对于编译器切换/d1clr:nomscorlib
这对我不起作用。此外,对于Silverlight的mscorlib引用也自动添加到编译输出中,而不在命令行选项中指定它。这就是我如何解决它。
加载程序集编辑器插件
将树导航到参考
从reflexil菜单中删除对非silverlight mscorlib的引用。
右键单击树的顶层以进行装配,并保存在reflexil菜单下。
我没有测试过所有的功能,但到目前为止我测试的功能都按预期工作了。
谢谢Ben,你的帖子为我节省了很多时间。我以为我将不得不移植我的库:)