跨语言Web服务实现






4.38/5 (8投票s)
2002年12月6日
5分钟阅读

68256

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 服务使用者应用程序。