C++/CLI 入门






4.72/5 (12投票s)
如果您打算编写 C++/CLI 应用程序,我将向您展示一些不那么明显的技巧。
引言
在撰写我上一篇关于绘制正确的选项卡控件的文章时,我决定创建一个该控件的 C++/CLI 版本会不错。嗯,事实证明它不像我最初想的那么简单。因此,我希望在这篇文章中分享我的经验,希望它对那些出于某种原因决定与 C++/CLI 斗争的人会有所帮助。在这里,我还要指出,本文并非面向专家、大师等。如果您觉得自己属于 Visual Studio 开发团队,那么本文不适合您 。
我们的目标
让我们想象一下,我们必须创建一个新的 Windows Forms(这就是重点)应用程序,并且我们被迫使用 C++/CLI。此外,我们只有现代版本的 Visual Studio(如 2012 或 2013)可供使用。
开始工作
在我们继续之前,我想在此达成一个共识:当我提到“Visual Studio”时,除非另有说明,我指的是 Visual Studio 2012/2013。
- 创建 Windows 应用程序
如果我们尝试这样做,很快就会发现 Visual Studio 中没有 C++/CLI 的此类模板。好的,我们将选择“CLR 控制台应用程序”并将其转换为 Windows 应用程序。“CLR 空项目”不是我们的选择,因为它甚至不会为应用程序创建入口点。请按照我的项目命名,这样您就可以找到我将引用的文件!在我们创建的项目中,根本没有窗体。让我们添加一个。右键单击解决方案资源管理器中的项目节点,然后选择添加>新建项... 选择新的 Windows 窗体。
该应用程序仍然是控制台。让我们做些魔法将其变成 Windows 应用程序。转到CppTutorial.cpp 并进行更正,使其如下所示
#include "stdafx.h" using namespace System; using namespace System::Windows::Forms; #include "MainForm.h" [STAThreadAttribute()] int main(array<System::String ^> ^args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew CppTutorial::MainForm()); return 0; }
现在运行您的应用程序。您会在后台看到一个难看的控制台窗口。要摆脱它,请转到项目的属性,选择配置属性>链接器>系统部分。将子系统设置为Windows。
为了使您的代码可编译,请转到配置属性>链接器>高级。将入口点设置为Main。
另外,稍微更正一下CppTutorial.cpp 中的代码。
#include "stdafx.h" using namespace System; using namespace System::Windows::Forms; #include "MainForm.h" [STAThreadAttribute()] void Main(array<System::String ^> ^args)// it's now void and starts with capital M { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew CppTutorial::MainForm()); }
构建并运行项目。恭喜!我们正在运行一个闪亮的新 Windows 应用程序。
- 体系结构切换
我们刚刚创建的应用程序是 32 位的。您可以使用配置管理器轻松将其设置为 64 位(我假设您知道那是什么)。但是,如果您想创建 MSIL 应用程序(即 Any CPU),与 C# 或 VB .NET 不同,您在那里找不到此类选项。我们该怎么办?好的,有一种方法。转到配置属性>通用并将公共语言运行时支持更改为
/clr:pure
或/clr:safe
构建了项目。我们现在这里有一个 Any CPU 程序集。您可以在此处阅读有关
/clr
开关的更多信息:此处。 - 更改 .NET 版本
最初,我们使用选定的 .NET Framework 4.5 创建了我们的项目。但是,如果我们改变主意了呢?现在我们希望它是 4。使用 C# 或 VB .NET 项目更改 .NET 版本很容易。使用 C++/CLI,您必须手动修改.vcxproj 文件。我们来做吧。右键单击您的项目并选择卸载项目。再次右键单击它并选择编辑 CppTutorial.vcxproj。找到看起来像这样的部分
<PropertyGroup Label="Globals"> <ProjectGuid>{Some GUID here}</ProjectGuid> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <Keyword>ManagedCProj</Keyword> <RootNamespace>CppTutorial</RootNamespace> </PropertyGroup>
将
TargetFrameworkVersion
更改为 v4.0。保存,然后右键单击解决方案资源管理器中的项目并选择重新加载项目。我们的项目现在是 .NET 4.0。您可以在项目属性中验证它。 - 程序集版本
打开AssemblyInfo.cpp 文件。您可以在此处更改很多信息。但在编译并查看 EXE 详细信息后,您会发现信息不在那里。这是使用 C++/CLI 的方法。为了方便起见,添加一个名为AssemblyInfo.h 的新头文件,并将以下代码放入其中(版本号和字符串内容由您决定)。
#pragma once #define Assembly_Copyright L"Copyright © Vladimir Svyatski 2015" #define Assembly_Description L"A sample application for CodeProject" #define File_Version 1,0,0,0 #define File_Version_Str "1.0.0.0" //CLR assembly version #define Assembly_Version L"1.0.0.0"
现在使您的AssemblyInfo.cpp 看起来像这样
#include "stdafx.h" using namespace System; using namespace System::Reflection; using namespace System::Runtime::InteropServices; #include "AssemblyInfo.h" // // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // [assembly:AssemblyTitleAttribute(L"CppTutorial")]; [assembly:AssemblyDescriptionAttribute(Assembly_Description)]; [assembly:AssemblyConfigurationAttribute(L"")]; [assembly:AssemblyCompanyAttribute(L"")]; [assembly:AssemblyProductAttribute(L"CppTutorial")]; [assembly:AssemblyCopyrightAttribute(Assembly_Copyright)]; [assembly:AssemblyTrademarkAttribute(L"")]; [assembly:AssemblyCultureAttribute(L"")]; // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // [assembly:AssemblyVersionAttribute(Assembly_Version)]; [assembly:ComVisible(false)]; [assembly:CLSCompliantAttribute(true)];
还没完,我们需要编辑app.rc。双击它,在资源视图中,右键单击app.rc 节点,选择资源包括... 在此处包含AssemblyInfo.h,如下所示。
单击确定(它很可能会显示一个警告,但没关系,只需接受它)。现在在资源视图中,添加一个新的版本资源。现在我们想将AssemblyInfo.h 中的定义放在这里,但 Visual Studio 每次将新资源添加到app.rc 时都会覆盖它们。我们将对其进行欺骗。向“资源文件”部分添加一个名为app.rc2 的新文件。再次修改您的资源包括:这次添加一个编译时指令。
#include "app.rc2"
在文本模式下打开app.rc,剪切
VERSIONINFO
资源并将其粘贴到app.rc2 中。app.rc2 应如下所示(包含来自AssemblyInfo.h 的定义)#ifdef APSTUDIO_INVOKED #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // Neutral resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION File_Version PRODUCTVERSION File_Version FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x0L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "041904b0" BEGIN VALUE "FileDescription", Assembly_Description VALUE "FileVersion", File_Version_Str VALUE "InternalName", "CppTutorial.exe" VALUE "LegalCopyright", Assembly_Copyright VALUE "OriginalFilename", "CppTutorial.exe" VALUE "ProductName", "CppTutorial" VALUE "ProductVersion", File_Version_Str END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x419, 1200 END END #endif
要编译项目,请确保在vcxproj 文件中将我们的app.rc2 指定为
None
<ItemGroup> <None Include="app.rc2" /> </ItemGroup>
构建项目,在 Windows 资源管理器中打开 EXE 详细信息,大功告成
- 签名程序集
这在 C# 或 VB .NET 中很容易完成。在 C++/CLI 中,它有点棘手。首先,我们需要一个 SNK 文件。我们可以通过 2 种方式创建它
- 通过控制台魔术使用sn.exe 实用程序。我在这里不描述这种方式。我们将其留给有兴趣的人作为练习。
- 我们可以创建一个临时的 C# 或 VB .NET 项目来生成 SNK。我们坚持使用这个。
继续,创建一个 C# 项目(选择 Windows 应用程序、控制台应用程序或其他任何内容并不重要)。打开其属性,然后在签名部分选中签名程序集。在下面的组合框中选择<新建...>。按您喜欢的方式填写对话框,但为了本教程的目的,请将签名文件命名为signature.snk。现在将生成的 SNK 文件复制到我们的 C++/CLI 项目目录中并将其包含到项目中。我们快完成了。打开项目的属性。在配置属性>链接器>高级部分,将密钥文件指定为
$(ProjectDir)signature.snk
,如下所示构建您的程序集,它现在已签名。
就是这样!我希望这篇文章在某些方面对您有所帮助。
历史
- 2015 年 2 月 13 日 - 提交初始版本