我有一个令人困惑的问题。我正在尝试制作一个使用WSDL的Web cleint。
我正在使用C++ RAD Studio 10 Seattle,但在RAD Studio XE8(旧版本)中发生了相同的问题。

1.我创建了一个多设备应用程序,添加了一个编辑组件和一个按钮。

2.我通过将WSDL文件的位置更改为“http://www.w3schools.com/webservices/tempconvert.asmx?WSDL”来创建WSDL导入程序,并将所有其他设置保留为默认值。

3.在按钮的ButtonClick事件上,我编写了两行代码:

 _di_TempConvertSoap Converter = GetTempConvertSoap(true,
 "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL");

 Edit1->Text = Converter->CelsiusToFahrenheit("32");

因此,经过这三个步骤,我得到了一个单元,它是具有表单和按钮事件的主要单元。 WSDL Importer生成了一个文件“tempconvert.cpp”。实际上,它只是将WSDL代码转换为C++代码,并定义了与服务器通信的方法。就我而言,我有两种方法:FahrenheitToCelsius()CelsiusToFahrenheit(),在示例中,我使用CelsiusToFahrenheit()

我将其编译为32位Windows平台,运行它,然后单击按钮,结果“89.6”出现在“编辑”组件的文本中。因此,这按预期工作。

但是,当我将目标平台更改为“Android”并在Android 4.1.2上使用手机“Samsung GT-I8262”并运行该项目时,它将停止并退出。我调试了问题,它停止在"tempconvert.cpp"方法中RegTypes()中的第一个命令处。
// ************************************************************************
//
// This routine registers the interfaces and types exposed by the WebService.
// ************************************************************************ //
static void RegTypes()
{
  /* TempConvertSoap */
  InvRegistry()->RegisterInterface(__delphirtti(TempConvertSoap), L"http://www.w3schools.com/webservices/", L"utf-8");
  InvRegistry()->RegisterDefaultSOAPAction(__delphirtti(TempConvertSoap), L"http://www.w3schools.com/webservices/%operationName%");
  InvRegistry()->RegisterInvokeOptions(__delphirtti(TempConvertSoap), ioDocument);
  /* TempConvertSoap.FahrenheitToCelsius */
  InvRegistry()->RegisterMethodInfo(__delphirtti(TempConvertSoap), "FahrenheitToCelsius", "",
                                    "[ReturnName='FahrenheitToCelsiusResult']", IS_OPTN);
  /* TempConvertSoap.CelsiusToFahrenheit */
  InvRegistry()->RegisterMethodInfo(__delphirtti(TempConvertSoap), "CelsiusToFahrenheit", "",
                                    "[ReturnName='CelsiusToFahrenheitResult']", IS_OPTN);
  /* TempConvertHttpPost */
  InvRegistry()->RegisterInterface(__delphirtti(TempConvertHttpPost), L"http://www.w3schools.com/webservices/", L"utf-8");
  InvRegistry()->RegisterDefaultSOAPAction(__delphirtti(TempConvertHttpPost), L"");
}
#pragma startup RegTypes 32

有人知道为什么会发生这种情况吗?我试过另外两部三星手机,但没有用。关闭程序的错误是“段错误(11)”,更确切地说,它停止在“System.pas”文件中的以下代码行:
u_strFromUTF8(PUChar(Dest), MaxDestChars, DestLen, MarshaledAString(Source), SourceBytes, ErrorConv);

这是一些有关该功能的信息:
  • u_strFromUTF8-将UTF-8字符串转换为UTF-16的函数。
  • UCHAR是Byte(在Delphi中),因此PUCHAR是指向Byte的指针。

  • 我无法确定此函数可能会出什么问题,该函数显然只能转换字符串。

    所以我的问题是,为什么该项目可以在Windows 32位版本上运行,但是在Android上却抛出Segmentation fault(11)?

    我希望我能找到解决这个问题的方法。我会继续寻找。

    谢谢,

    Zdravko Donev :)

    更新:

    我反汇编了这行:
    InvRegistry()->RegisterInterface(__delphirtti(TempConvertSoap), L"http://www.w3schools.com/webservices/", L"utf-16");
    

    要得到 :
      TInvokableClassRegistry *Class = InvRegistry();
      TTypeInfo *Info = __delphirtti(TempConvertSoap);
      UnicodeString Namespace = "http://www.w3schools.com/webservices/";
      UnicodeString WSDLEncoding = "utf-8";
    
      Class->RegisterInterface(Info, Namespace, WSDLEncoding);
    

    而且我看到在调用InvRegistry()函数时出现了问题,但是由于无法访问该函数的源代码,我仍然没有发现问题。

    最佳答案

    我找到了解决方案。

    我删除了这一行

    #pragma startup RegTypes 32
    

    并在创建表单时成功调用了RegTypes()方法。

    关于android - 适用于Android的C++ Builder WSDL客户端,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32844855/

    10-10 17:48