14

アプリケーションに簡単にリンクできる単純な C++ WebService クライアント ライブラリを探しています。

できればこのライブラリ:

  • 任意の SOAP WebService へのアクセスに使用できます (そのため、URL、WebService 名、WebService メソッド、およびすべての引数を引数として関数呼び出しに渡すことができます)。
  • C++ アプリケーションで静的にリンクできます (したがって、DLL はありません)。
  • フリーウェアまたは低価格で入手可能
  • 私のアプリケーションではロイヤリティフリーで使用できます
  • Web サービスにその WSDL を照会し、使用可能なメソッド名、メソッドの引数、およびそれらのデータ型を返すことができます

誰かが .NET に答える前に: そこに行って、試してみてください。.NET に対する私の主な反論は次のとおりです。

すでに Google を使用してこの情報を調べましたが、見つかりませんでした。

ありがとう

編集: これをさらに明確にするために、次のようなコード(またはこのスタイルの何か)を記述できるものが本当に必要です:

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

3 に答える 3

6

gSOAP を見たことがありますか? あなたのニーズに合うと思います。

http://gsoap2.sourceforge.net/

于 2010-11-26T13:27:50.130 に答える
4

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

たとえば、PeriodicTable Web サービスを使用するコードは次のとおりです。

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);
            }
        }
    }
}

このコードでは明示的に使用methods[0]してmethods[1]いますが、実際にはもちろんメソッド名を確認します。この例では、周期表のすべての元素の名前を取得してから、酸素の原子量を取得します。

この例には、プロキシをサポートするロジックがまだ含まれていません。これはまだ追加する必要がありますが、現時点では、これで私の最大の問題、つまり汎用 SOAP クライアントを使用することが解決されます。

編集:

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

于 2010-11-29T13:23:39.313 に答える
1

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

Axis2C は上記のほとんどをチェックします。静的リンクを確認してください。.

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

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

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

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

乾杯!

于 2010-11-26T16:11:34.567 に答える