65.9K
CodeProject 正在变化。 阅读更多。
Home

您的第一个托管 C++ Web 服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (10投票s)

2001年4月3日

CPOL

4分钟阅读

viewsIcon

309520

downloadIcon

3124

使用托管扩展的 C++ 编写您的第一个 WebService 的简介。

引言

本文假设您熟悉 声明和使用托管类型 以及 .NET 垃圾回收器

如果您使用 C# 或 VB.NET,创建第一个 Web 服务将非常容易(有关详细信息,请参阅我 之前的文章)。使用 .NET 中的托管 C++ 编写 WebService 也非常简单,但有几个“陷阱”可能会造成一些令人沮丧的时刻。

我的第一个建议是使用 Visual Studio .NET 向导来创建您的 WebService(事实上,对于您刚开始使用时所有的应用程序来说,这是一个绝佳的主意)。如果您正在更新 .NET 的各种 beta 版本,这一点尤其重要。在一个版本中完全可以接受的内容,在另一个版本中可能无法编译,并且很难弄清楚您缺少哪个环节。

使用向导可以在几分钟内启动并运行一个托管 C++ WebService,但当您尝试一些更具风险的操作时,事情会变得有点奇怪。

在此示例中,我通过使用向导创建了一个名为 MyCPPService 的服务。只需选择 File | New Project 并运行向导即可创建一个 C++ WebService。

将定义一个名为 CPPWebService 的新命名空间,并且在该命名空间内将是实现您 webservice 的类和结构。在此示例中,我称此类为 MyService。向导创建的其他文件包括充当服务代理的 .asmx 文件;用于配置设置的 config.web 文件;以及用于服务发现的 .disco 文件。一旦您编译了该类,您的程序集将存储在 /bin 目录下的 CPPWebService.dll 中。

我想模仿我 之前的文章 中创建的 C# WebService,但做了一些小改动来演示使用值类型和引用类型。考虑到这一点,我在命名空间中定义了一个值类型结构 ClientData 和一个托管引用类型 ClientInfo,它们都将分别包含一个名称和 ID(stringint 值)。 

__value public struct ClientData
{
	String *Name;
	int	ID;
};
__gc public class ClientInfo
{
	String *Name;
	int	ID;
};

为了返回对象数组,还声明了一个快速的 typedef。

typedef ClientData ClientArray[];

同样,我将我的 MyService 类定义为一个简单的托管 C++ 类,其中包含三个方法。

  • MyMethod 是一个简单的方法,它返回单个整数。
  • GetClientData 返回单个 ClientData 结构。
  • GetClientsData 返回 ClientInfo 对象数组。
// CPPWebService.h

#pragma once
#using "System.EnterpriseServices.dll"

namespace CPPWebService
{
	__value public struct ClientData
	{
		String *Name;
		int	ID;
	};

	__gc public class ClientInfo
	{
		String *Name;
		int	ID;
	};

	typedef ClientData ClientArray[];

	__gc class MyService 
	{
	public:
		[WebMethod] 
		int MyMethod();

		[WebMethod]
		ClientData GetClientData();

		[WebMethod]
		ClientArray GetClientsData(int Number);
	};
}

关于函数原型要 ध्यान देने योग्य important thing 是 [WebMethod] 属性 - 这会告知编译器该方法将是 web service 的方法,并且应该提供适当的支持和基础结构。您附加此属性的方法也必须是公共可访问的。

实现 (.cpp) 文件如下。

#include "stdafx.h"
#using <mscorlib.dll>
#using "System.Web.dll"
#using "System.Web.Services.dll"

using namespace System;
using namespace System::Web;
using namespace System::Web::Services;

#include "CPPWebService.h"

namespace CPPWebService
{
	int MyService::MyMethod()
	{
		return 42;
	}

	ClientData MyService::GetClientData()
	{
		ClientData data;
		data.Name = new String("Client Name");
		data.ID = 1;

		return data;
	}

	ClientArray MyService::GetClientsData(int Number)
	{
		// simple sanity checks
		if (Number < 0 || Number > 10)
			return 0;

		ClientArray data = new ClientData __gc[Number];

		if (Number > 0 && Number <= 10)
		{
			for (int i = 0; i < Number; i++)
			{
				data[i].Name = new String("Client ");
				data[i].Name->Concat(i.ToString());
				data[i].ID = i;
			}
		}

		return data;
	}
};

请注意 i.ToString() 语法的用法。在 .NET 中,值类型(如 int 和 enum)可以关联方法。i.ToString() 只是调用变量 iInt32::ToString()

与 beta 1 相比,.NET beta 2 的一个巨大改进是您不再需要与 XmlIncludeAttribute 类进行繁琐的操作来告知序列化器有关您的结构。一些导致问题或更糟 - 完全无法运行的 bug 也得到了修复。使用 MC++ 编写 WebService 现在与 C# 一样容易,其优点是可以混合搭配本机和托管代码,同时保留 C++ 的强大功能。

进行更改后,您可以构建项目,然后通过在 Visual Studio 的 Solution Explorer 中右键单击 CPPWebService.asmx 并选择“在浏览器中查看”来测试服务。测试页面如下所示。

单击其中一个方法(例如 GetClientsData)将显示一个代理页面,允许您直接从浏览器调用该方法。GetClientsData 方法接受一个 int 参数,您可以在编辑框中输入。

调用后,将返回以下结果:

结论

使用托管扩展的 Visual C++ 编写 WebServices 与使用 C# 或 VB.NET 编写它们一样简单,只要您记住一些简单的事情:使用属性,将类声明为托管的,并使其公共可访问。使用 Visual Studio.NET 向导使编写和部署这些服务变得轻而易举,但即使您想手动完成,涉及的步骤也极其简单。

历史

10 月 18 日 - 为 .NET beta 2 更新

© . All rights reserved.