我需要让非托管的 Windows C++ 客户端与 WCF 服务对话。 C++ 客户端可以在 Win2000 和更高版本上运行。我可以控制 WCF 服务和正在使用的 C++ API。由于它用于专有应用程序,因此最好尽可能使用 Microsoft 的东西,绝对不是 GNU 许可的 API。那些让它工作的人,你能分享一个如何让它工作的分步过程吗?
到目前为止,我已经研究了以下选项:
还有更多想法吗?请仅在您自己实际使用它时才回答。
编辑 1 :我为任何我可能感到困惑的人道歉:我正在寻找一种从没有安装 .NET 框架的客户端调用 WCF 服务的方法,因此使用基于 .NET 的帮助程序库不是一种选择,它必须是纯非托管 C++
最佳答案
基本思想是用 C# 为您的客户端编写 WCF 代码(这样更容易)并使用 C++ 桥 dll 来弥合非托管 C++ 代码和用 C# 编写的托管 WCF 代码之间的差距。
以下是使用 Visual Studio 2008 和 .NET 3.5 SP1 的分步过程。
``
[ServiceContract]
public interface IHelloService
{
[OperationContract]
string SayHello(string name);
}
public class HelloService : IHelloService
{
public string SayHello(string name)
{
return String.Format("Hello, {0}!", name);
}
}
using System.ServiceModel;
using System.ServiceProcess;
public partial class Service1 : ServiceBase
{
private ServiceHost _host;
public Service1()
{
InitializeComponent();
}
protected override void OnStart( string [] args )
{
_host = new ServiceHost( typeof( HelloService ) );
_host.Open();
}
protected override void OnStop()
{
try {
if ( _host.State != CommunicationState.Closed ) {
_host.Close();
}
} catch {
}
}
}
Hello 服务的代理类。 注意:我似乎总是遇到此过程生成的 Reference.cs 文件的编译问题。我不知道是我做错了还是有错误,但解决这个问题的最简单方法是直接修改 Reference.cs 文件。该问题通常是命名空间问题,可以轻松解决。请注意,这是一种可能性。对于本示例,我已将 HelloServiceClient.ServiceReference1 更改为简单的 HelloService(以及任何其他必需的更改)。
和 References 设置,添加对 .NET System、System.ServiceModel 和 mscorlib 程序集的引用。单击确定按钮。
#ifndef __IHelloServiceClientBridge_h__
#define __IHelloServiceClientBridge_h__
#include <string>
#ifdef HELLOSERVICECLIENTBRIDGE_EXPORTS
#define DLLAPI __declspec(dllexport)
#else
#define DLLAPI __declspec(dllimport)
#pragma comment (lib, "HelloServiceClientBridge.lib") // if importing, link also
#endif
class DLLAPI IHelloServiceClientBridge
{
public:
static std::string SayHello(char const *name);
};
#endif // __IHelloServiceClientBridge_h__
#ifndef __HelloServiceClientBridge_h__
#define __HelloServiceClientBridge_h__
#include <vcclr.h>
#include "IHelloServiceClientBridge.h"
#ifdef _DEBUG
#using<..\HelloServiceClient\bin\Debug\HelloServiceClient.dll>
#else
#using<..\HelloServiceClient\bin\Release\HelloServiceClient.dll>
#endif
class DLLAPI HelloServiceClientBridge : IHelloServiceClientBridge
{ };
#endif // __HelloServiceClientBridge_h__
#include "HelloServiceClientBridge.h"
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::ServiceModel;
using namespace System::ServiceModel::Channels;
std::string IHelloServiceClientBridge::SayHello(char const *name)
{
std::string rv;
gcroot<Binding^> binding = gcnew WSHttpBinding();
gcroot<EndpointAddress^> address = gcnew EndpointAddress(gcnew String("http://localhost:8731/Design_Time_Addresses/WindowsService1/HelloService/"));
gcroot<HelloService::HelloServiceClient^> client = gcnew HelloService::HelloServiceClient(binding, address);
try {
// call to WCF Hello Service
String^ message = client->SayHello(gcnew String(name));
client->Close();
// marshal from managed string back to unmanaged string
IntPtr ptr = Marshal::StringToHGlobalAnsi(message);
rv = std::string(reinterpret_cast<char *>(static_cast<void *>(ptr)));
Marshal::FreeHGlobal(ptr);
} catch (Exception ^) {
client->Abort();
}
return rv;
}
服务电话。在 MFC 窗体上,双击 Say Hello!按钮以生成 ButtonClicked 事件处理程序。使事件处理程序看起来像这样:
#include "IHelloServiceClientBridge.h"
#include <string>
void CMFCApplicationDlg::OnBnClickedButton1()
{
try {
std::string message = IHelloServiceClientBridge::SayHello("Your Name Here");
AfxMessageBox(CString(message.c_str()));
} catch (...) {
}
}
调用承载在 Windows NT 服务中的 WCF Hello 服务的 SayHello() 方法(顺便说一下,它应该仍在运行)。然后返回值显示在消息框中。
希望您可以从这个简单的示例中推断出满足您的需求。如果这不起作用,请告诉我,以便我修复帖子。
关于c++ - 为非托管 C++ 客户端创建 WCF 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/686452/