我正在尝试写一个" 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方法之前抛出异常......
任何想法有什么不对?谢谢!
答案 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>