• FreeBASIC通过Delphi7 DLL调用MS SOAP使用VB6 Webservice


    前几篇笔记习练了IIS soapis30配置、VB6 webservice创建、Delphi7和VB6 webservice访问:

    VB6 COM webservice发布,VB.NET和Delphi 7 对webservice访问,及MS Soap Toolkit 3.0在IIS上的ISAPI配置_Mongnewer的博客-CSDN博客

    本篇笔记重点编写 Delphi7 DLL 对MS soap3 进行封装,让FreeBASIC通过Delphi7的DLL封装,访问IIS上的Webservice。

    主要任务是:1. 编写 Delphi7 DLL, 2. 编写FreeBasic调用程序。

    • 编写 Delphi7 DLL

    打开Delphi7 , File -> New -> others -> DLL wizard

    在创建的DLL项目Project2上引入 Microsoft Soap Type Library v3.0(Version 3.0)

    在Project2.pas中use引用的 MSSOAPLib30_TLB

    编写三个function,一个是初始化dpSoap3Init、一个是dpEchoString、一个是dpAddNumbers,全部程序如下:

    1. library Project2;
    2. uses
    3. Windows,
    4. Messages,
    5. SysUtils,
    6. Variants,
    7. Classes,
    8. StrUtils,
    9. COMobj,
    10. MSSOAPLib30_TLB in 'C:\Program Files (x86)\Borland\Delphi7\Imports\MSSOAPLib30_TLB.pas';
    11. type
    12. TinRecord = record
    13. vi_param1: short;
    14. vi_param2: short;
    15. End;
    16. var
    17. mySoapClient3: OleVariant;
    18. function dpSoap3Init(): integer; stdcall;
    19. begin
    20. try
    21. mySoapClient3:= CreateOleObject('MSSOAP.SoapClient30');
    22. mySoapClient3.mssoapinit('http://192.168.3.113/Soap3DocSamples/DocSample1/Server/TestWEBservice.WSDL', 'TestWEBservice', 'Sample1SoapPort');
    23. Result:= 0;
    24. except
    25. Result:= 1;
    26. end;
    27. end;
    28. function dpEchoString(inChars: pchar): pchar; stdcall;
    29. var
    30. I: integer;
    31. fromFBstring: string;
    32. fromWSDLstring: string;
    33. p: pchar;
    34. begin
    35. fromFBstring:= StrPas(inChars);
    36. fromFBstring:= Trim(fromFBstring);
    37. fromWSDLstring:= mySoapClient3.EchoString(fromFBstring);
    38. p:= pchar(fromWSDLstring);
    39. Result:= p;
    40. end;
    41. function dpAddNumbers(inType: Pointer): smallint;
    42. var
    43. nBlock: TinRecord;
    44. begin
    45. CopyMemory(@nBlock, inType, sizeof(nBlock));
    46. Result:= mySoapClient3.AddNumbers(nBlock.vi_param1, nBlock.vi_param2);
    47. end;
    48. exports
    49. dpSoap3Init,
    50. dpEchoString,
    51. dpAddNumbers;
    52. {$R *.res}
    53. begin
    54. end.

    写好代码,然后编译生成 Project.DLL,放到FreeBasic项目的Release下(后面会进一步讲到)。

    接下来,创建FreeBASIC标准32位x86窗体项目,放上一些控件,并在窗体通用中放入代码 Dim Shared library As Any Ptr, 这个library将作为动态装入Project2.DLL的指针,供整个程序运行期使用。

    在窗体Create创建时,动态调入Project2.DLL,这个DLL要放在工程的 Release下面,与工程的exe放在一起。调入Project2.DLL后取得指针 library,利用指针找到 dpSoap3Init 过程入口地址,然后调用它,并在Text1中显示调用结果,为0表示成功,为1表示失败。

    1. Sub Form1_WM_Create(hWndForm As hWnd, UserData As Integer)
    2. library = DyLibLoad("Project2") '就文件名,不能带 .DLL
    3. If (library = 0) Then
    4. AfxMsg "加载DLL失败"
    5. Return
    6. End If
    7. Dim retVal As Integer
    8. Dim FuncSoap As Function() As Integer
    9. FuncSoap = DyLibSymbol(library, "dpSoap3Init")
    10. If (FuncSoap = 0) Then
    11. AfxMsg "无法从开发DLL例题库中检索dpSoap3Init()函数的地址"
    12. Return
    13. End If
    14. retVal = FuncSoap()
    15. Text1.text = Str(retVal) 'Should be 0 if success
    16. End Sub

    当项目运行结束时,释放 Project2.DLL,此时会用到 library 指针。

    1. Function Form1_WM_Close(hWndForm As hWnd) As LResult
    2. DyLibFree(library)
    3. Function = False ' 返回 TRUE 阻止关闭窗口。
    4. End Function

    dpEchoString的实现。找到dpEchoString函数入口,将字符数组的首地址交给它,然后取得返回的字符数组的首地址。依据返回的首地址,变回Project.DLL发送出来的完整字符串。字符数组长度为256,足以满足使用要求。

    1. '===============================================================================================
    2. Dim fHello As Function(ByVal As UByte Ptr) As UByte Ptr
    3. fHello = DyLibSymbol(library, "dpEchoString")
    4. If (fHello = 0) Then
    5. AfxMsg "无法从开发DLL例题库中检索dpEchoString()函数的地址"
    6. Return
    7. End If
    8. Dim I As Integer
    9. Dim J As UByte Ptr
    10. Dim sTempString As String
    11. Dim sParam(255) As UByte
    12. sTempString = Trim(Text6.text) & " "
    13. memcpy(@sParam(0), StrPtr(sTempString), Len(sTempString))
    14. J= fHello(@sParam(0))
    15. sTempString = ""
    16. For I = 0 To 255
    17. sTempString = sTempString + Chr(*(J+I))
    18. Next I
    19. Text3.text = Trim(sTempString)

    再看一下Project2.DLL中对应的代码,它接收来自FreeBASIC的指针,变成字符串后发送给MS Soap Toolkit3的SoapClient3实例mySoapClient3,并接收它返回的字符串,其pchar指针返回给FreeBASIC

    1. function dpEchoString(inChars: pchar): pchar; stdcall;
    2. var
    3. I: integer;
    4. fromFBstring: string;
    5. fromWSDLstring: string;
    6. p: pchar;
    7. begin
    8. fromFBstring:='';
    9. for I:=0 to 255 do
    10. begin
    11. fromFBstring:= fromFBstring + inChars^;
    12. inc(inChars);
    13. end;
    14. fromFBstring:= Trim(fromFBstring);
    15. fromWSDLstring:= mySoapClient3.EchoString(fromFBstring);
    16. p:= pchar(fromWSDLstring);
    17. Result:= p;
    18. end;

    dpAddNumbers调用使用了变量结构体,取得dpAddNumbers地址后通过它发送结构的地址指针,并在函数返回时获得16位short类型数据值。

    1. Type TParam1
    2. vi_Param1 As Short
    3. vi_Param2 As Short
    4. End Type
    5. Dim fAddNumbers As Function(ByVal As Any Ptr) As Short
    6. fAddNumbers = DyLibSymbol(library, "dpAddNumbers")
    7. If (fAddNumbers = 0) Then
    8. AfxMsg "无法从开发DLL例题库中检索dpAddNumbers()函数的地址"
    9. Return
    10. End If
    11. Dim Resultval As Short
    12. Dim nParam1 As TParam1
    13. nParam1.vi_Param1 = Val(Text4.text): nParam1.vi_Param2 = Val(Text5.text)
    14. Resultval = fAddNumbers(@nParam1)
    15. Text2.text = Str(Resultval)

    在Project2.DLL中,也使用了一个定义好的结构体TinRecord。当收到FreeBASIC的结构体指针后,直接将其指向的内容复制给TinRecord结构体实例,然后直接将结构体中的变量发送给mySoapClient3,并将返回的结果返送给FreeBASIC

    1. function dpAddNumbers(inType: Pointer): smallint;
    2. var
    3. nBlock: TinRecord;
    4. begin
    5. CopyMemory(@nBlock, inType, sizeof(nBlock));
    6. Result:= mySoapClient3.AddNumbers(nBlock.vi_param1, nBlock.vi_param2);
    7. end;
    1. type
    2. TinRecord = record
    3. vi_param1: short;
    4. vi_param2: short;
    5. End;

    至此,FreeBASIC通过Delphi7 DLL顺利访问IIS的VB6 webservice

    FreeBASIC有个开发中的axSuite是做COM访问的,我还没有试用过。这篇笔记只是针对MS Soap Toolkit 3.0的习练。

  • 相关阅读:
    BSV 上的付费解密智能合约
    完美转发与底层原理剖析(引用折叠)
    k8s篇之四、service
    【数据结构与算法】骑士周游算法/马踏棋盘算法的介绍和程序实现
    Go语言中的数组、切片和映射解析
    【C语言】文件相关函数详解
    【2014年数据结构真题】
    MySQL1——喵喵期末不挂科
    【蓝桥杯物联网赛项学习日志】Day4 关于USART/UART
    ms-gamingoverlay一直跳出来怎么解决?
  • 原文地址:https://blog.csdn.net/weixin_45707491/article/details/132752609