2010-11-26 19 views
12

私のアプリケーションに簡単にリンクできる簡単なC++ WebServiceクライアントライブラリを探しています。 C++用の汎用WebService(SOAP)クライアントライブラリ

することは好ましくは、このライブラリー:

  • 任意のSOAPのWebサービスにアクセスするために使用することができます
  • (私は、関数呼び出しの引数としてURL、Webサービス名、Webサービスメソッドとすべての引数を渡すことができます)
  • は、C++アプリケーションに静的にリンクすることができます(これがないDLLの)
  • 低コスト
  • のフリーウェアまたは利用可能である私のアプリケーション
  • に無償で使用できるWeb SERVICを照会することができますeをWSDLに追加して、利用可能なメソッド名、メソッドの引数とそのデータ型を返します。

誰かが.NETに回答する前に、そこにいました。 .NETに対する私の主な反論は、以下のとおりです。

  • プロキシを生成することができますが(私の質問のためDynamically call SOAP service from own scripting languageを参照してください、それは.NETがWebサービス名を確認するためにリフレクションを使用しているため、その後生成されたプロキシコードでWebサービス名を変更することは不可能ですその場でプロキシクラスを生成するという問題)
  • については、常に私はすでにこの情報を調べるためにGoogleを使用

正常に動作するようには思えませんが、私は1つを見つけることができませんでした。

おかげ

EDIT:

SoapClient mySoapClient; 
mySoapClient.setURL("http://someserver/somewebservice"); 
mySoapClient.setMethod("DoSomething"); 
mySoapClient.setParameter(1,"Hello"); 
mySoapClient.setParameter(2,12345); 
mySoapClient.sendRequest(); 
string result; 
mySoapClient.getResult(result); 

ません動的コード生成: は、私は本当に私は(このスタイルでか何か)のようなコードを書くことができます何かをしたい、これをさらに明確にするため。

答えて

4

私は、オンザフライで生成されたアセンブリを使用して解決策を見つけました(前回はうまく動作しませんでした)。出発点はhttp://refact.blogspot.com/2007_05_01_archive.htmlです。

など。私は明示的にmethods[0]methods[1]を使用しますが、現実には、あなたがコースのメソッド名をチェックします。このコードでは

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 
using System.Web; 
using System.Web.Services; 
using System.Web.Services.Description; 
using System.CodeDom; 
using System.CodeDom.Compiler; 
using System.Xml.Serialization; 
using System.IO; 
using System.Reflection; 

namespace GenericSoapClient 
{ 
class Program 
    { 
    static void method1() 
     { 
     Uri uri = new Uri("http://www.webservicex.net/periodictable.asmx?WSDL"); 
     WebRequest webRequest = WebRequest.Create(uri); 
     System.IO.Stream requestStream = webRequest.GetResponse().GetResponseStream(); 

     // Get a WSDL 
     ServiceDescription sd = ServiceDescription.Read(requestStream); 
     string sdName = sd.Services[0].Name; 

     // Initialize a service description servImport 
     ServiceDescriptionImporter servImport = new ServiceDescriptionImporter(); 
     servImport.AddServiceDescription(sd, String.Empty, String.Empty); 
     servImport.ProtocolName = "Soap"; 
     servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties; 

     CodeNamespace nameSpace = new CodeNamespace(); 
     CodeCompileUnit codeCompileUnit = new CodeCompileUnit(); 
     codeCompileUnit.Namespaces.Add(nameSpace); 

     // Set Warnings 

     ServiceDescriptionImportWarnings warnings = servImport.Import(nameSpace, codeCompileUnit); 

     if (warnings == 0) 
      { 
      StringWriter stringWriter = 
       new StringWriter(System.Globalization.CultureInfo.CurrentCulture); 

      Microsoft.CSharp.CSharpCodeProvider prov = 
       new Microsoft.CSharp.CSharpCodeProvider(); 

      prov.GenerateCodeFromNamespace(nameSpace, 
       stringWriter, 
       new CodeGeneratorOptions()); 

      string[] assemblyReferences = 
       new string[2] { "System.Web.Services.dll", "System.Xml.dll" }; 

      CompilerParameters param = new CompilerParameters(assemblyReferences); 

      param.GenerateExecutable = false; 
      param.GenerateInMemory = true; 
      param.TreatWarningsAsErrors = false; 

      param.WarningLevel = 4; 

      CompilerResults results = new CompilerResults(new TempFileCollection()); 
      results = prov.CompileAssemblyFromDom(param, codeCompileUnit); 
      Assembly assembly = results.CompiledAssembly; 
      Type service = assembly.GetType(sdName); 

      //MethodInfo[] methodInfo = service.GetMethods(); 

      List<string> methods = new List<string>(); 

      // only find methods of this object type (the one we generated) 
      // we don't want inherited members (this type inherited from SoapHttpClientProtocol) 
      foreach (MethodInfo minfo in service.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) 
       { 
       methods.Add(minfo.Name); 
       Console.WriteLine (minfo.Name + " returns " + minfo.ReturnType.ToString()); 
       ParameterInfo[] parameters = minfo.GetParameters(); 
       foreach (ParameterInfo pinfo in parameters) 
        { 
         Console.WriteLine(" " + pinfo.Name + " " + pinfo.ParameterType.ToString()); 
        } 
       } 

      // Create instance of created web service client proxy 
      object obj = assembly.CreateInstance(sdName); 

      Type type = obj.GetType(); 

      object[] args0 = new object[] { }; 
      string result0 = (string)type.InvokeMember(methods[0], BindingFlags.InvokeMethod, null, obj, args0); 
      Console.WriteLine(result0); 

      object[] args1 = new object[] { "Oxygen" }; 
      string result1 = (string)type.InvokeMember(methods[1], BindingFlags.InvokeMethod, null, obj, args1); 
      Console.WriteLine(result1); 
      } 
     } 
    } 
} 

:これは、周期表のWebサービスを使用するためのコードです。この例では、周期表のすべての要素の名前を取得し、次に酸素の原子量を取得します。

この例には、まだプロキシをサポートするロジックが含まれていません。私はまだこれを追加する必要がありますが、現時点では、私の最大の問題、すなわち一般的なSOAPクライアントを持っています。

EDIT:

私は、このコードは、C#で、私はもともとC++ソリューションを求めていた知っているが、このコードは、それは私はまだ限られた部分に使用することができた(.NET環境で働くことができることを証明しています私のアプリケーションの)、私はおそらく私の問題を解決するC + +/NETにこのコードを書き換えます。

+0

それは良い点です! C++ Builder環境に移植できると思いますか?またはそれは.NETとReflectionに依存していますか? – bluish

+0

@bluish、これは本当に.Netに依存しています。コードは.Netを使用してクライアントクラスを生成し、.Net C#コンパイラを使用してコンパイルし、.NETリフレクションを使用してクラスを呼び出します。 – Patrick

+3

OPの問題は解決してうれしく思いますが、私はこの質問の回答がC#のように受け入れられないと信じています。具体的にはC++に関する質問です... – zgyarmati

5

gSOAPを見ましたか?私はそれがあなたのニーズに適していると思います。

http://gsoap2.sourceforge.net/

+1

gSOAPがCPPコードを生成するようです。これでも私は顧客固有のCPPコードを生成する必要があります。私が望むのは、単純なC++クラス(またはクラスのセット)です。ここでは、URL、Webサービス名、Webサービスメソッド、および引数を単純に指定できます。 – Patrick

+0

私はC++ SOAPインターフェイスに関する多くの研究を行ってきました.gSOAPは最高のものです。 *一口*幸運! – Starkey

+1

おそらくgSOAPはWSDLを事前に知っている方が最適です。しかし、Webサービスの名前、メソッド、引数がすべての顧客で異なる場合はどうすればよいでしょうか?設定ファイルからこの情報を読み込み、設定ファイルの内容に応じて呼び出しを行いたいのですが? – Patrick

0

Axis2C: http://axis.apache.org/axis2/c/core/index.html

Axis2Cは、上記のほとんどを刻み、静的リンクをチェックしてください。

EDIT:リストの最後のいくつかのメッセージでは、静的リンクは不完全です。以下はまだ保持されています:

おそらく私は質問を正しく理解していません。呼び出したWebサービスは、エンドポイントURLと操作&のパラメータを指定する必要があります。

サービスを動的に「発見」して、&を呼び出すオプションを提示していますか?もしそうなら、私はこれが可能であると疑う。

一般的なフレームワークを参照している場合、SOAPメッセージはクライアント側の責任です。いくつかのツールキットAPIの下でそれらをラップするのに問題はないはずです。 WSDLコードの生成は必須ではありません。いくつかのサービスをゼロから作成しました。つまり、エンドポイント、サービス、およびSOAPメッセージ、パラメータ、ヘッダーなどを設定できます。

乾杯!

+1

いくつかの例(またはそのリンク)を投稿してください。 – bluish

関連する問題