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

跨语言Web服务实现

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (8投票s)

2002年12月6日

5分钟阅读

viewsIcon

68256

downloadIcon

1664

托管 C++ 和 C# 之间的跨语言 XML Web 服务实现。

引言

除非您对 COM 有深刻的了解,否则在 .NET 出现之前,使用多种语言创建应用程序是一件非常困难的事情。基于 XML 的 Web 服务正在成为在分布式系统之间传输信息的非常流行的方法,尽管 Web 服务本身在 .NET Framework 推出之前就已经存在了。 .NET Framework 使我们能够快速开发 Web 服务,即使在公式中引入了多种语言。本文的目的有两点:我想更多地了解托管 C++,并认为将核心数据库部分用托管 C++ 编写将是一次很好的学习经历,同时将功能暴露给 C# Web 服务。我实际上之前并没有编写过 Web 服务,所以我想将两者结合起来会是一个很好的例子。我将尝试解释一切;然而,熟悉 C++ 中类本身的 A 概念是有帮助的。最近有人问是否有可能在 .NET 中,多种语言在一个程序中协同工作,希望这个例子能够说明这种可能性。

托管 C++ 程序集核心

我们需要开始创建一个新的托管 C++ 程序集;这是大部分实际工作所在的地方。如果您对 C# 有一定的了解,您会注意到托管 C++ 使用类似的符号来包含命名空间,但略有不同。对于我们的程序集,我们需要包含以下命名空间(列在 mcpp.h 头文件中)

using namespace System;
using namespace System::Data;
using namespace System::Data::SqlClient;
using namespace System::Xml;

在托管 C++ 中,我们还需要识别命名空间所在的文件,这是通过#using语句完成的,这在某种程度上类似于#include用于在标准 C++ 中包含头文件。我们需要为我们的示例项目在 Stdafx.h 头文件中包含以下文件。

#using <mscorlib.dll>
#using <System.dll>
#using <system.data.dll>
#using <System.Xml.dll> 

当我们创建项目时,您会发现 Visual Studio.NET 创建了一个名为 MyNumber 的基类。下一步是找到包含类描述的头文件,并添加一个函数原型来识别我们的新方法,我们将使用它从 SQL Server 获取数据。您会发现 mcpp.h 头文件包含出类框架。打开此文件后,您应该会看到一个初始类声明,看起来像这样,我已经添加了下面的原型

namespace mcpp
{
	public __gc class MyNumber
	{
		// TODO: Add your methods for this class here.
	public:
	int GetWebStat(); // Add this function prototype

	};
}

现在我们需要在项目中的 mcpp.cpp 文件中为该函数添加实现。

int mcpp::MyNumber::GetWebStat()
{
	SqlConnection* mySQLConnection;
	SqlCommand* sqlCommand;
	SqlDataReader* dr;
	String* sql;
	int i;
	try
	{
	  sql = S"select count(*) as myCount from site_stats";
           // Assign our connection object with the connection string.
	  mySQLConnection = new SqlConnection(S"server=[YourServerName];" +
				               "database=[YourDatabaseName];" +
				               "Integrated Security=yes;");
           // Open the databse connection.
	  mySQLConnection->Open ();

           // Tie the SqlCommand object to our connection and SQL statement.
	  sqlCommand = new SqlCommand(sql, mySQLConnection);
           // Fills the SqlDataReader with content.
	  dr = sqlCommand->ExecuteReader();
	  while(dr->Read())
	  {
		i = Convert::ToInt32(dr->get_Item(S"myCount")->ToString());
	  }
	  return i;
	}
	catch(Exception* e)
	{
		Console::Write(e->ToString());
	}
	__finally
	{
		mySQLConnection->Close();
	}
}

现在您可以将此程序集构建并编译到您的 .DLL 中,这是我们在托管 C++ 世界中需要做的全部。

C# Web 服务

下一步是创建一个新的 C# Web 服务,以公开我们刚刚在托管 C++ 程序集中编写的功能。您需要加载 Visual Studio.NET 并选择 ASP.NET Web 服务作为项目模板。

语言集成

为了将托管 C++ 程序集集成到我们的 C# 项目中,我们需要做两件事。首先,转到项目并选择“添加引用”。将加载一个对话框,您需要选择右上角的“浏览”。您需要选择托管 C++ 项目中的程序集 .DLL,它位于 Debug 或 Release 文件夹中,具体取决于您如何构建发布版本。在代码顶部,所有 using 语句都位于此处,用于标识项目中的所有命名空间,请包含以下内容

using mccp;

这是托管 C++ 程序集之前使用的命名空间的名称。现在我们只需在 C# 中添加一个新方法并创建我们的托管 C++ 类的实例,真的就是这么简单。请参考以下代码作为 Web 服务剩余 C# 源的示例。真正有趣的是,如果您曾使用过 C# 中的 Windows Forms,您的类声明不再继承自 System.Windows.Forms.Form,而是继承自 System.Web.Services.WebService。添加以下函数到您的 C# 代码后,您可以保存并构建项目。如果您以前从未接触过基于 XML 的 Web 服务,Chris Maunder 编写了 您的第一个 C# Web 服务 [^],这是一个很好的额外信息来源。您可能需要为您的 Web 服务器映射一个虚拟目录,就像我在这个示例中所做的一样。

[WebMethod(Description="This is an implementation of a" +
		" cross language web service between Managed C++ and C#.")]
public int MyWebStats()
{
	int i;
         // Create an instance of our MC++ class.
	mcpp.MyNumber m = new mcpp.MyNumber();
         // Simply call the method from our class object.
	i = m.GetWebStat();
	return i;
}

在应用程序中消耗 Web 服务

在我们的应用程序中消耗这些新的基于 XML 的 Web 服务的能力可以为任何应用程序增加很大的可扩展性。我包含了另一个消耗我们已演示的 Web 服务的项目。要在您的项目中包含 Web 服务,您需要通过右键单击项目中的“引用”来选择“添加 Web 引用”。这将加载一个对话框,供您查找您的 Web 服务。您可以在对话框中输入以下 URL 来查找我的示例服务:http://www.developernotes.com/web_svr/service1.asmx。一旦找到服务,您就可以点击右下角的“添加引用”按钮。我创建了一个简单的窗体并添加了以下代码来访问我们新的 Web 服务;令人惊讶的是,这些底层工作都为我们处理好了。

private void button1_Click(object sender, System.EventArgs e)
{
   this.label2.Text = "Checking...";
   this.label2.Refresh();
   // Creates an instance of our class.
   com.developernotes.www.MyWebSite stats = new com.developernotes.www.MyWebSite();
   // Calls our method and assigns the return value to our label.
   this.label2.Text = stats.MyWebStats().ToString();
}

实时示例

您可以在我的网站上看到一个实时示例,它运行着 XML 数据流:实时 XML Web 服务示例

结论

这个简单的例子应该足以说明 .NET Framework 如何轻松地使多种语言之间能够轻松地相互通信,而没有 COM 所引入的那种琐碎的细节。任何问题、评论或批评都可以发布在下方。

更新历史

  • 2002 年 12 月 6 日 - 初始发布。
  • 2002 年 12 月 8 日 - 添加了 Web 服务使用者应用程序。
© . All rights reserved.