调用Web服务的C ++ Builder控制台应用程序(hello world)

时间:2012-02-21 19:18:49

标签: web-services soap c++builder

我正在尝试写一个" Hello World"使用C ++ Builder的示例。这是我的第一个项目,所以我可能犯了一个简单的错误。

我想创建一个调用计算器Web服务的控制台应用程序。

我打开C ++ Builder 2007并创建一个控制台应用程序。出现一个名为File1.cpp的cpp文件。这是内容:

//---------------------------------------------------------------------------
#include <iostream.h>
#include <vcl.h>
#pragma hdrstop
#include "calculator.h"

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
    double a, b;

    cout << "Enter the values to sum\n";
    cout << "A: ";
    cin >> a;
    cout << "B: ";
    cin >> b;

    cout << "\nA+B:";
    cout << GetCalculatorSoap()->Add(1,2);

    cout << "\n\nPress any key to continue...";
    getchar();

    return 0;
}
//---------------------------------------------------------------------------

此外,我将soap代理添加到New-&gt; Other-&gt; WebService-&gt; WSDL Importer中。 使用WSDL http://www.dneonline.com/calculator.asmx?WSDL

此操作添加了calculator.cpp:

// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : http://www.dneonline.com/calculator.asmx?WSDL
//  >Import : http://www.dneonline.com/calculator.asmx?WSDL:0
// Encoding : utf-8
// Version  : 1.0
// (21/02/2012 19:48:31 - - $Rev: 10138 $)
// ************************************************************************ //

#include <vcl.h>
#pragma hdrstop

#if !defined(calculatorH)
#include "calculator.h"
#endif  

namespace NS_calculator {

_di_CalculatorSoap GetCalculatorSoap(bool useWSDL, 
  AnsiString addr, THTTPRIO* HTTPRIO)
{
  static const char* defWSDL= "http://www.dneonline.com/calculator.asmx?WSDL";
  static const char* defURL = "http://www.dneonline.com/calculator.asmx";
  static const char* defSvc = "Calculator";
  static const char* defPrt = "CalculatorSoap";
  if (addr=="")
    addr = useWSDL ? defWSDL : defURL;
  THTTPRIO* rio = HTTPRIO ? HTTPRIO : new THTTPRIO(0);
  if (useWSDL) {
    rio->WSDLLocation = addr;
    rio->Service = defSvc;
    rio->Port = defPrt;
  } else {
    rio->URL = addr;
  }
  _di_CalculatorSoap service;
  rio->QueryInterface(service);
  if (!service && !HTTPRIO)
    delete rio;
  return service;
}


// ************************************************************************ //
// This routine registers the interfaces and types exposed by the WebService.
// ************************************************************************ //
static void RegTypes()
{
  /* CalculatorSoap */
  InvRegistry()->RegisterInterface(__interfaceTypeinfo(CalculatorSoap),             
     L"http://tempuri.org/", L"utf-8");
  InvRegistry()->RegisterDefaultSOAPAction(__interfaceTypeinfo(CalculatorSoap), 
     L"http://tempuri.org/%operationName%");
  InvRegistry()->RegisterInvokeOptions(__interfaceTypeinfo(CalculatorSoap), 
     ioDocument);
}
#pragma startup RegTypes 32

};     // NS_calculator

当我运行应用程序时,它会在调用GetCalculatorSoap() - &gt; Add(1,2)时引发异常:

---------------------------
Debugger Exception Notification
---------------------------
Project Test.exe raised exception class EOleSysError 
  with message 'CoInitialize has not been called'.
---------------------------
Break   Continue   Help   
---------------------------

调试它似乎GetCalculatorSoap()执行正常,但在调用Add方法之前抛出异常......

任何想法有什么不对?谢谢!

1 个答案:

答案 0 :(得分:4)

错误消息告诉您问题是什么 - 尚未调用CoInitialize。 (实际上,最好是调用CoInitializeEx,但要么可以使用。)

您的SOAP代码使用COM方法,因此必须首先初始化COM。这是基于每个线程完成的。

您可以在CoInitialize(NULL);功能的开头调用main'来解决此问题。不要忘记在CoUnitialize();结束时拨打main

在Delphi中,CoInitialize/CoUninitialize单位声明了ActiveX。在C ++ Builder中,它似乎在OBJBASE.H中(快速搜索在那里找到它,这也是MSDN documentation中指出的内容。

(如果您习惯于编写基于VCL表单的应用程序,那么您之前就不会看到这个; VCL会自动为您初始化COM。您现在正在看它,因为您正在编写一个控制台应用程序。)< / p>