दिलचस्प पोस्ट
सी ++ स्रोत कोड में यूनिकोड का उपयोग करना बूलियन क्यों करता है। टॉस्ट्रिंग आउटपुट "ट्रू" और "सच" नहीं है क्यों __init __ () हमेशा __new __ () के बाद कहा जाता है? आईडी कॉलम के साथ डेटा फ़्रेम में सूची स्तंभ को समतल करें क्या GOF सिंगलटन पैटर्न के लिए कोई व्यवहार्य विकल्प हैं? संशोधित तिथि के आधार पर सॉर्ट करने के लिए स्कैंडर () क्या मैं .NET / C # से अन्य प्रक्रियाओं के कमांड लाइन तर्क प्राप्त कर सकता हूं? किसी स्थिति या कम पर सेट बिट्स को गिनने का कारगर तरीका क्या है? लघुकरण के दौरान डीबग जावास्क्रिप्ट कोड बाहर निकालें java.lang.NoClassDefFound त्रुटि: com.google.android.gms.internal.zzmp दाएं से बाएं टेक्स्ट HTML इनपुट DIV तत्व पर कुंजी प्रेस (या कुंजीडाउन) ईवेंट कैप्चर करें क्या वेब साइट्स को वास्तव में ब्राउज़रों के लिए पूरा करने की आवश्यकता है जिनके पास जावास्क्रिप्ट सक्षम नहीं है? कैसे मेवेन प्रोजेक्ट संस्करण को बाश कमांड लाइन में प्राप्त करें GIT_WORK_TREE क्या है, मुझे इस ENV var को सेट करने की आवश्यकता क्यों नहीं है, अब क्यों?

अप्रबंधित C ++ क्लाइंट के लिए WCF सेवा बनाएँ

WCF सेवा से बात करने के लिए मुझे अप्रबंधित Windows C ++ क्लाइंट्स प्राप्त करने की आवश्यकता है I सी ++ क्लाइंट Win2000 और बाद में चल रहे हैं। मेरा WCF सेवा दोनों पर एक नियंत्रण है और जो C ++ API का उपयोग किया जा रहा है चूंकि यह एक मालिकाना एप्लिकेशन के लिए है, संभवतः माइक्रोसॉफ्ट सामान का उपयोग करना बेहतर है, निश्चित रूप से जीएनयू लाइसेंस प्राप्त एपीआई नहीं। आपमें से जो इसे काम करते हैं, क्या आप एक कदम-दर-चरण प्रक्रिया को साझा कर सकते हैं कि यह कैसे काम करे?

मैंने अब तक निम्न विकल्पों पर शोध किया है:

  • WWSAPI – अच्छा नहीं, Win 2000 क्लाइंट पर काम नहीं करेगा I
  • एटीएल सर्वर, एक संदर्भ के रूप में निम्नलिखित गाइड का इस्तेमाल किया। मैंने उल्लिखित चरणों का पालन किया (नीति रिफॉर्स्ट को हटाने और डब्लूएसडीएल को समतल करना), हालांकि परिणामस्वरूप डब्ल्यूएसडीएल अभी भी स्प्रोक्सि द्वारा उपयोग नहीं कर पा रहा है

कोई और विचार? कृपया उत्तर दें यदि आप वास्तव में स्वयं को काम कर रहे हैं

1 संपादित करें : मैं किसी के लिए माफी मांगता हूं जो मुझे भ्रमित कर सकता है: मैं जो ग्राहक की तलाश कर रहा था वह क्लाइंट (ओं) से डब्लूसीएफ सेवा को कॉल करने का एक तरीका था, जहां कोई .NET ढांचा स्थापित नहीं होता है, इसलिए .NET- आधारित सहायक लाइब्रेरी का उपयोग करना एक विकल्प नहीं है, यह शुद्ध अप्रबंधित C ++ होना चाहिए

Solutions Collecting From Web of "अप्रबंधित C ++ क्लाइंट के लिए WCF सेवा बनाएँ"

मूल विचार यह है कि सी # में अपने क्लाइंट के लिए WCF कोड लिखना (यह बस इतना आसान है) और सी # में लिखे गए अपने अप्रबंधित C ++ कोड और प्रबंधित WCF कोड के बीच अंतर को कम करने के लिए C ++ पुल डीएलएल का उपयोग करें।

यहां एनआईटी 3.5 एसपी 1 के साथ विजुअल स्टूडियो 2008 का उपयोग करके कदम-दर-चरण प्रक्रिया है।

  1. पहली बात यह है कि WCF सेवा और इसे होस्ट करने का एक साधन बना है। यदि आपके पास यह पहले से है, तो नीचे चरण 7 पर जाएं। अन्यथा, यहां से दिए गए चरणों का पालन करते हुए एक Windows NT सेवा बनाएँ। प्रोजेक्ट के लिए VS2008 द्वारा प्रदत्त डिफ़ॉल्ट नाम और प्रोजेक्ट में जोड़े जाने वाले किसी भी कक्षा का उपयोग करें। यह Windows NT सेवा WCF सेवा की मेजबानी करेगा

    • परियोजना में HelloService नामक एक WCF सेवा जोड़ें ऐसा करने के लिए, समाधान एक्सप्लोरर विंडो में परियोजना को राइट-क्लिक करें और Add | New Item … मेनू आइटम का चयन करें। नई आइटम जोड़ें संवाद में, सी # डब्ल्यूसीएफ सेवा टेम्पलेट चुनें और जोड़ें बटन पर क्लिक करें। यह HelloService को एक इंटरफ़ेस फ़ाइल (IHelloService.cs), एक क्लास फ़ाइल (HelloService.cs), और एक डिफ़ॉल्ट सेवा कॉन्फ़िगरेशन फ़ाइल (app.config) के रूप में प्रोजेक्ट को जोड़ता है।

    • इस तरह HelloService को परिभाषित करें:

[ServiceContract] public interface IHelloService { [OperationContract] string SayHello(string name); } public class HelloService : IHelloService { public string SayHello(string name) { return String.Format("Hello, {0}!", name); } } 
  • इस तरह दिखने के लिए ऊपर चरण 1 में बनाए गए Service1 वर्ग को संशोधित करें:

     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 { } } } 
  • परियोजना का निर्माण

  • दृश्य स्टूडियो 2008 कमांड प्रॉम्प्ट को खोलें परियोजना के लिए आउटपुट निर्देशिका पर जाएं निम्न टाइप करें: `installutil WindowsService1.exe 'यह आपके स्थानीय मशीन पर Windows NT सेवा स्थापित करता है। सेवा नियंत्रण कक्ष खोलें और Service1 सेवा शुरू करें काम करने के लिए नीचे चरण 9 के लिए यह करना महत्वपूर्ण है।

    1. दृश्य स्टूडियो 2008 का एक दूसरा उदाहरण खोलें और एक एमएफसी एप्लिकेशन बनाएं, जो लगभग दूर के रूप में आप WCF से प्राप्त कर सकते हैं। उदाहरण के तौर पर, मैंने बस एक डायलॉग एमएफसी एप्लिकेशन बनाया और एक सैम हैलो कहा! बटन इसे करने के लिए समाधान एक्सप्लोरर में प्रोजेक्ट को राइट-क्लिक करें और गुण मेनू विकल्प चुनें। सामान्य सेटिंग्स के अंतर्गत, आउटपुट डायरेक्टरी को .. में बदलें। \ Bin \ Debug सी / सी ++ सामान्य सेटिंग्स के तहत, जोड़ें .. \ HelloServiceClientBridge अतिरिक्त निर्देशिकाएँ शामिल करें। लिंकर सामान्य सेटिंग्स के अंतर्गत, अतिरिक्त .. लाइब्रेरी निर्देशिका में डीबग करें। ठीक बटन पर क्लिक करें
  • फ़ाइल मेनू से, Add | New Project … मेनू आइटम का चयन करें। सी # कक्षा लाइब्रेरी टेम्प्लेट चुनें। HelloServiceClient को नाम बदलें और ठीक बटन पर क्लिक करें। समाधान एक्सप्लोरर में प्रोजेक्ट को राइट-क्लिक करें और गुण मेनू विकल्प चुनें। बिल्ड टैब में, आउटपुट पथ को .. \ bin \ डीबग में बदलें, ताकि विधानसभा और app.config फ़ाइल MFC अनुप्रयोग के रूप में एक ही निर्देशिका में हो। इस पुस्तकालय में सेवा संदर्भ, अर्थात्, डब्ल्यूसीएफ प्रॉक्सी क्लास, विंडोज़ NT सर्विस में होस्ट WCF हैलो सेवा के लिए होगा।

  • समाधान Explorer में, HelloServiceClient प्रोजेक्ट के लिए संदर्भ फ़ोल्डर को राइट-क्लिक करें और सेवा संदर्भ जोड़ें … मेनू विकल्प का चयन करें। पता फ़ील्ड में, हैलो सेवा का पता टाइप करें। यह उपरोक्त चरण 2 में बनाए app.config फ़ाइल में आधार पते के बराबर होना चाहिए। गो बटन पर क्लिक करें सेवा सूची में हैलो सेवा को दिखाना चाहिए। नमस्कार सेवा के लिए स्वचालित रूप से प्रॉक्सी वर्ग (एसएएस) उत्पन्न करने के लिए ठीक बटन पर क्लिक करें। नोट: मुझे हमेशा इस प्रक्रिया से उत्पन्न संदर्भ.cs फ़ाइल के साथ संकलन समस्याओं में चलने लगता है। मुझे नहीं पता कि मैं इसे गलत कर रहा हूं या यदि कोई बग है, लेकिन इसे ठीक करने का सबसे आसान तरीका संदर्भ.cs फ़ाइल को सीधे संशोधित कर रहा है। समस्या आम तौर पर एक नामांकन समस्या है और इसे न्यूनतम प्रयास के साथ तय किया जा सकता है बस पता है कि यह एक संभावना है इस उदाहरण के लिए, मैंने HelloServiceClient.ServiceReference1 को सिर्फ HelloService (किसी भी अन्य आवश्यक परिवर्तनों के साथ) में बदल दिया है।

  • एमसीसी एप्लीकेशन को डब्लूसीएफ सेवा से बातचीत करने की अनुमति देने के लिए, हमें एक प्रबंधित सी ++ "पुल" डीएलएल का निर्माण करना होगा। फ़ाइल मेनू से, Add | New Project … मेनू आइटम का चयन करें। सी + + Win32 प्रोजेक्ट टेम्प्लेट चुनें। HelloServiceClientBridge नाम बदलें और ठीक बटन पर क्लिक करें। अनुप्रयोग सेटिंग्स के लिए, DLL में अनुप्रयोग प्रकार को बदलें और रिक्त प्रोजेक्ट चेकबॉक्स को चेक करें। फिनिश बटन पर क्लिक करें

  • करने के लिए पहली चीज परियोजना गुणों को संशोधित करती है। समाधान एक्सप्लोरर में प्रोजेक्ट को राइट-क्लिक करें और गुण मेनू विकल्प चुनें। सामान्य सेटिंग्स के अंतर्गत, आउटपुट डायरेक्टरी को .. में बदलें .. \ bin \ डिबग करें और सामान्य भाषा रनटाइम समर्थन विकल्प को आम भाषा रनटाइम सपोर्ट (/ सीएलआर) में बदलें। फ्रेमवर्क और संदर्भ सेटिंग्स के तहत, .NET सिस्टम, System.ServiceModel, और mscorlib विधानसभाओं के लिए एक संदर्भ जोड़ें। ठीक बटन पर क्लिक करें

  • HelloServiceClientBridge प्रोजेक्ट में निम्न फ़ाइलें जोड़ें – HelloServiceClientBridge.h, IHelloServiceClientBridge.h, और HelloServiceClientBridge.cpp।

  • इस तरह दिखने के लिए IHelloServiceClientBridge.h संशोधित करें:

     #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__ 
  • इस तरह देखने के लिए HelloServiceClientBridge.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__ 
  • । सीपीपी फ़ाइल के लिए सिंटैक्स प्रबंधित C ++ का उपयोग करता है, जो कुछ करने में प्रयुक्त होता है इस तरह दिखने के लिए HelloServiceClientBridge.cpp संशोधित करें:

     #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; } 
  • सिएहेलो () WCF सेवा कॉल को आमंत्रित करने के लिए केवल एकमात्र काम एमएफसी एप्लिकेशन को अपडेट कर रहा है। एमएफसी फॉर्म पर, सैलो हैलो पर डबल क्लिक करें! बटन को बटन जनरेट करने वाला हेन्डलर उत्पन्न करने के लिए इस तरह ईवेंट हैंडलर देखो:

     #include "IHelloServiceClientBridge.h" #include <string> void CMFCApplicationDlg::OnBnClickedButton1() { try { std::string message = IHelloServiceClientBridge::SayHello("Your Name Here"); AfxMessageBox(CString(message.c_str())); } catch (...) { } } 
  • एप्लिकेशन को चलाएं और कहो नमस्कार! बटन। इससे ऐप को विंडोज़ एनटी सेवा में होस्ट की डब्लू सी एफ हैलो सेवा की साहोल्लो () पद्धति का आह्वान करने का कारण बनता है (जो अभी भी चल रहा है)। वापसी मान तब संदेश बॉक्स में प्रदर्शित होता है

उम्मीद है कि आप अपनी आवश्यकताओं के अनुरूप इस सरल उदाहरण से एक्सट्रपलेशन कर सकते हैं। अगर यह काम नहीं करता है, तो कृपया मुझे बताएं कि मैं पोस्ट को ठीक कर सकता हूं।

जो दिलचस्पी रखते हैं, उनके लिए मुझे एक अर्द्ध-कार्यरत एटीएल सर्वर समाधान मिला। निम्नलिखित होस्ट कोड है, नोटिस यह BasicHttpBinding का उपयोग कर रहा है, यह केवल एक है जो एटीएल सर्वर के साथ काम करता है:

  var svc = new Service1(); Uri uri = new Uri("http://localhost:8200/Service1"); ServiceHost host = new ServiceHost(typeof(Service1), uri); var binding = new BasicHttpBinding(); ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService1), binding, uri); endpoint.Behaviors.Add(new InlineXsdInWsdlBehavior()); host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true }); var mex = host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); host.Open(); Console.ReadLine(); 

InlineXsdInWsdlBehavior के लिए कोड यहां पाया जा सकता है । एक महत्वपूर्ण परिवर्तन को इनलाइनएक्सडीएनडब्ल्यूएसडीएल बीहीवियर के साथ करने की ज़रूरत है ताकि जटिल प्रकारों में शामिल होने के दौरान इसे ठीक से काम करने के लिए ठीक से काम किया जा सके। यह स्प्रोक्सि में बग के कारण होता है, जो कि नेमस्पेस एलियंस को ठीक से नहीं गुंजाता है, इसलिए डब्ल्यूएसडीएल में नाम स्थान की उपनामों को दोहरा नहीं सकता है या स्प्रोक्सि बाहर निकलेगा। यहां कार्य करने वाले परिवर्तन हैं:

  public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context) { int tnsCount = 0; XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas; foreach (WsdlDescription wsdl in exporter.GeneratedWsdlDocuments) { // // Recursively find all schemas imported by this wsdl // and then add them. In the process, remove any // <xsd:imports/> // List<XmlSchema> importsList = new List<XmlSchema>(); foreach (XmlSchema schema in wsdl.Types.Schemas) { AddImportedSchemas(schema, schemaSet, importsList, ref tnsCount); } wsdl.Types.Schemas.Clear(); foreach (XmlSchema schema in importsList) { RemoveXsdImports(schema); wsdl.Types.Schemas.Add(schema); } } } private void AddImportedSchemas(XmlSchema schema, XmlSchemaSet schemaSet, List<XmlSchema> importsList, ref int tnsCount) { foreach (XmlSchemaImport import in schema.Includes) { ICollection realSchemas = schemaSet.Schemas(import.Namespace); foreach (XmlSchema ixsd in realSchemas) { if (!importsList.Contains(ixsd)) { var new_namespaces = new XmlSerializerNamespaces(); foreach (var ns in ixsd.Namespaces.ToArray()) { var new_pfx = (ns.Name == "tns") ? string.Format("tns{0}", tnsCount++) : ns.Name; new_namespaces.Add(new_pfx, ns.Namespace); } ixsd.Namespaces = new_namespaces; importsList.Add(ixsd); AddImportedSchemas(ixsd, schemaSet, importsList, ref tnsCount); } } } } 

अगला कदम C ++ हेडर उत्पन्न करना है:

 sproxy.exe /wsdl http://localhost:8200/Service1?wsdl 

और फिर सी ++ प्रोग्राम इस तरह दिखता है:

 using namespace Service1; CoInitializeEx( NULL, COINIT_MULTITHREADED ); { CService1T<CSoapWininetClient> cli; cli.SetUrl( _T("http://localhost:8200/Service1") ); HRESULT hr = cli.HelloWorld(); //todo: analyze hr } CoUninitialize(); return 0; 

परिणामी C ++ कोड परिसर प्रकारों को बहुत निर्लज्ज रूप से संभालता है, सिवाय इसके कि वह ऑब्जेक्ट के लिए शून्य को निर्दिष्ट नहीं कर सकता।

मैं WCF काम करने के लिए एक सी # प्रबंधित वर्ग बनाना होगा और क्लास को C ++ क्लाइंट के लिए COM ऑब्जेक्ट के रूप में प्रदर्शित करेगा

आप एक SOAP ग्राहक को कुछ हद तक आसानी से उपयोग किए गए एमएस साबुन टूलकिट का उपयोग कर सकते हैं। दुर्भाग्यवश, इस पर एनएटी पर जाने के बाहर कोई विकल्प नहीं लगता है।

क्या आप एक आरईएसटी वेब सेवा प्रकाशित कर सकते हैं और एमएसएक्सएमएम सीएम पुस्तकालय का उपयोग कर सकते हैं – पहले से ही इंस्टॉल किया जाना चाहिए, इसमें एक्सएमएल पार्सर और एक एचटीटीपी पुस्तकालय है।

http://msdn.microsoft.com/en-us/library/ms763742.aspx