2010-11-26 3 views
12

내 응용 프로그램에 쉽게 연결할 수있는 간단한 C++ WebService 클라이언트 라이브러리를 찾고 있습니다. C++ 용 일반 웹 서비스 (SOAP) 클라이언트 라이브러리

하는 것은 바람직이 라이브러리 :

  • 어떤 SOAP의 WebService에 액세스 할 수 있습니다
  • (그래서 함수 호출에 인수로 URL, WebService에 이름, WebService에 방법과 모든 인수를 전달할 수 있습니다)
  • 는 C의 ++ 응용 프로그램 (그래서 DLL의)
  • 내 응용 프로그램을 무상으로 사용할 수있는 저렴한 비용으로 프리웨어 또는 사용할 수 없습니다
  • 웹 아가를 조회 할 수 있습니다에 정적으로 링크 할 수 있습니다 e를 사용하여 사용 가능한 메소드 이름, 메소드의 인수 및 해당 데이터 유형을 리턴하십시오.

누구든지 .NET에 응답하기 전에 : 시도해보십시오. .NET에 대한 내 주요 반대는 다음과 같습니다

  • 당신은 프록시를 생성 할 수 있지만 (내 질문에 대한 Dynamically call SOAP service from own scripting language 참조는 .NET은 WebService에 이름을 확인하는 반사를 사용하기 때문에, 이후에 생성 된 프록시 코드에서 WebService에 이름을 변경하는 것은 불가능합니다 즉석에서 프록시 클래스를 생성하는 그 문제)
  • 에 관한 것은 항상 내가 이미이 정보를 찾기 위해 구글을 사용

제대로 작동하지 않는 것,하지만 난 하나를 찾을 수 없습니다.

감사

편집 :

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

이전에 작동하지 못했던 on-the-fly 생성 어셈블리를 사용하여 솔루션을 찾았습니다. 출발 지점은 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); 
      } 
     } 
    } 
} 

:이 주기율표 웹 서비스를 사용하는 코드입니다. 이 예제에서는 주기율표의 모든 원소의 이름을 얻은 다음 산소의 원자량을 구합니다.

이 예에는 아직 프록시를 지원하는 논리가 포함되어 있지 않습니다. 나는 여전히 이것을 추가 할 필요가 있지만, 현재로서는 가장 큰 문제, 즉 일반적인 SOAP 클라이언트를 가지고있다.

편집 :

이 코드는 C#을 내가 원래 C++ 솔루션을 요구하고 알고 있지만,이 코드는 아직도 제한된 지역에서 사용할 수있는 (.NET 환경에서 작업 할 수 있음을 증명 내 응용 프로그램의), 그리고 아마도이 코드를 C++/.NET으로 다시 작성하여 내 문제를 해결할 것입니다.

+0

좋은 지적입니다! C++ Builder 환경으로 포팅 될 수 있다고 생각하십니까? 또는 .NET과 Reflection에 종속적입니까? – bluish

+0

@blueish, 이것은 .Net에 실제로 의존합니다. 이 코드는 .Net을 사용하여 클라이언트 클래스를 생성 한 다음 .Net C# 컴파일러를 사용하여 컴파일하고 .Net reflection을 사용하여 클래스를 호출합니다. – Patrick

+3

비록 OP의 문제가 해결되어서 기쁩니다 만,이 질문에 대한 대답은 C#에서와 같이 C#에서 특히 그렇듯이이 대답은 받아 들여지지 않을 수도 있습니다. – zgyarmati

5

gSOAP을 보았습니까? 나는 그것이 당신의 필요에 알맞을 것이라고 생각합니다.

http://gsoap2.sourceforge.net/

+1

gSOAP에서 CPP 코드를 생성하는 것처럼 보입니다. 그래도 고객 전용 CPP 코드를 생성해야합니다. 내가 원한 것은 URL, 웹 서비스 이름, 웹 서비스 메서드 및 인수를 지정할 수있는 간단한 C++ 클래스 (또는 클래스 집합)입니다. – Patrick

+0

저는 C++ SOAP 인터페이스에 대한 많은 연구를 해왔습니다. gSOAP이 최고입니다. * 한숨 * 행운을 빌어 요! – Starkey

+1

아마도 gSOAP은 WSDL을 미리 알고있는 경우 가장 좋습니다. 그러나 webservice 이름, 메소드 및 인수가 모든 고객마다 다를 수 있다면, 구성 파일에서이 정보를 읽고 구성 파일의 내용에 따라 호출하고 싶습니다. – Patrick

0

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

Axis2C 위의 대부분을 틱, 정적 링크를 확인하시기 바랍니다. .

EDIT : 목록의 마지막 몇 개의 메시지만큼 정적 연결이 불완전합니다. 아래는 여전히 보유하고 있습니다 :

아마 나는 정확하게 질문을 이해하지 못합니다. 호출 한 모든 웹 서비스는 끝점 URL과 작업 & 매개 변수를 지정해야합니다.

& 서비스를 동적으로 "검색하는 중"이라고 말하는가? 그렇다면 나는 이것이 가능하다는 것을 의심한다.

일반 프레임 워크를 언급하는 경우 SOAP 메시지는 클라이언트 측 책임입니다.일부 툴킷 API로는 문제를 일으키지 않아야합니다. WSDL 코드 생성은 필수 사항이 아닙니다. 몇 가지 서비스를 처음부터 작성했습니다. 예를 들어, 엔드 포인트, 서비스 및 SOAP 메시지, 매개 변수, 헤더 등을 설정할 수 있습니다.

건배!

+1

일부 예제 (또는 링크)를 게시 할 수 있습니까? – bluish

관련 문제