SAP offers a library, called LIBRFC32, to use RFC with external programming languages. With the next steps I will show how to use this library with PureBasic. You find a lot of stuff about LIBRFC32 in the WWW, but the most of it is not really actual. I work and test with LIBRFC version 7.10 and a non-unicode SAP Netweaver ™ system 7.01.
Bibliography
- SAP help portal - LIBRFC32, http://help.sap.com/saphelp_nw70ehp1/he ... ameset.htm
Help of SAP Remote Function Call API from LIBRFC32, 21.09.2009
RFC SDK Guide, SAP Release 6.40, SAP AG, Walldorf, 2004
SAP R/3® Kommunikation mit RFC und VB, Patrick Theobald, Vieweg Verlag, 2003 ISBN 3-528-05878-1 
In the first step we will do nothing but connect and disconnect a SAP® system. At first we fill a few constants with the necessary arguments to identify the system and the user. Now look at the main procedure: we open the library LIBRFC32 and get a few informations about it. Then we connect the SAP® system with the procedure ConnectSAP. We use the constants and open the connect with RfcOpenEx. You get the handle of the RFC connection back. Check the connect with the transaction SMGW in the SAP® system. Now we disconnect the SAP® system with RfcClose, in the DisConnectSAP procedure, and close the library.
Code: Select all
; Begin-----------------------------------------------------------------
  ; Directives----------------------------------------------------------
    $LPP
    EnableExplicit
  ; Constants-----------------------------------------------------------
    Enumeration
      #RFCLib
    EndEnumeration
    #ASHost = "localhost"
    #SysNr = "00"
    #Client = "000"
    #User = "BCUSER"
    #PassWord = "minisap"
    #Language = "EN"
  ; Structures----------------------------------------------------------
    XIncludeFile "librfc32.structures.pbi"
  ; Procedure ConnectSAP------------------------------------------------
    Procedure.l ConnectSAP()
      ; Variables-------------------------------------------------------
        Protected ConString.s = #NULL$
        Protected RfcErrorInfoEx.RFC_ERROR_INFO_EX
      ConString = "ASHOST=" + #ASHost
      ConString = ConString + " SYSNR=" + #SysNr
      ConString = ConString + " CLIENT=" + #Client
      ConString = ConString + " USER=" + #User
      ConString = ConString + " PASSWD=" + #PassWord
      ConString = ConString + " LANG=" + #Language
      ;ConString = ConString + " RFC_TRACE=1"
      ;ConString = ConString + " ABAP_DEBUG=1"
      ConString = ConString + #NULL$
      ProcedureReturn CallFunction(#RFCLib, "RfcOpenEx", @ConString, _
        RfcErrorInfoEx)
    EndProcedure
  ; Procedure DisConnectSAP---------------------------------------------
    Procedure DisConnectSAP(hRFC.l)
      CallFunction(#RFCLib, "RfcClose", hRFC)
    EndProcedure
  ; Procedure Main------------------------------------------------------
    Procedure Main()
      ; Variables-------------------------------------------------------
        Protected hRFC.l = 0
        Protected Release.l, Level.l, Number.l
      CallDebugger
      If OpenLibrary(#RFCLib, "librfc32.dll")
        ; Version of LibRFC---------------------------------------------
          CallFunction(#RFCLib, "RfcGetPatchLevel", @Release, @Level, _
            @Number)
          Debug "Library-Release = " + Str(Release)
          Debug "Patch-Level = " + Str(Level)
          Debug "Patch-Number = " + Str(Number)
        hRFC = ConnectSAP()
        If hRFC
          ; ------------------------------------------------------------
          ;
          ; Check connection with TAC SMGW in the SAP system
          ;
          ; ------------------------------------------------------------
          DisConnectSAP(hRFC)
        EndIf
        CloseLibrary(#RFCLib)
      EndIf
    EndProcedure
; Main------------------------------------------------------------------
  Main()
; End-------------------------------------------------------------------
EndIn the one and a half step we will do a little bit more. After the connect we will get some SAP® system information with the function module RFC_SYSTEM_INFO. We define exporting, importing, changing and table parameters to transfer this information to the function module. RFC_SYSTEM_INFO only needs the importing parameter, all others are null. We call the function module with the function RfcCallReceiveEx and found a lot of system informations in the structure RFCSI. You see, how easy it is to call remote of a function module in a SAP© system. You only need the parameter and table structure to transfer data between your application and the SAP® system.
Code: Select all
; Begin-----------------------------------------------------------------
  ; Directives----------------------------------------------------------
    $LPP
    EnableExplicit
  XIncludeFile "librfc32.standard.pbi"
  ; Procedure Main------------------------------------------------------
    Procedure Main()
      ; Variables-------------------------------------------------------
        Protected hRFC.l = 0
        Protected rfc_rc.l = 0
        Protected rfcsi.RFCSI
        Protected Exception.l = 0
        Dim Exporting.RFC_PARAMETER(32)
        Dim Importing.RFC_PARAMETER(32)
        Dim Changing.RFC_PARAMETER(32)
        Dim Tables.RFC_TABLE(32)
      CallDebugger
      If OpenLibrary(#RFCLib, "librfc32.dll")
        hRFC = ConnectSAP()
        If hRFC
          Exporting(0)\name = #Null
          Importing(0)\name = @"RFCSI_EXPORT"
          Importing(0)\nlen = 12
          Importing(0)\addr = @rfcsi
          Importing(0)\leng = SizeOf(rfcsi)
          Importing(0)\type = #RFCTYPE_CHAR;
          Importing(1)\name = #Null
          Changing(0)\name = #Null
          Tables(0)\name = #Null
          If CallFunction(#RFCLib, "RfcCallReceiveEx", hRFC, _
            @"RFC_SYSTEM_INFO", @Exporting(), @Importing(), _
            @Changing(), @Tables(), @Exception) = #RFC_OK
            Debug "Host: " + rfcsi\rfchost
            Debug "SID: " + rfcsi\rfcsysid
            Debug "DBHost: " +rfcsi\rfcdbhost
          EndIf
          DisConnectSAP(hRFC)
        EndIf
        CloseLibrary(#RFCLib)
      EndIf
    EndProcedure
; Main------------------------------------------------------------------
  Main()
; End-------------------------------------------------------------------
EndCode: Select all
; Begin-----------------------------------------------------------------
  ; Constants-----------------------------------------------------------
    XIncludeFile "librfc32.constants.pbi"
    Enumeration
      #RFCLib
    EndEnumeration
    #ASHost = "localhost"
    #SysNr = "00"
    #Client = "000"
    #User = "BCUSER"
    #PassWord = "minisap"
    #Language = "EN"
  ; Structures----------------------------------------------------------
    XIncludeFile "librfc32.structures.pbi"
  ; Procedure ConnectSAP------------------------------------------------
    Procedure.l ConnectSAP()
      ; Variables-------------------------------------------------------
        Protected ConString.s = #NULL$
        Protected RfcErrorInfoEx.RFC_ERROR_INFO_EX
      ConString = "ASHOST=" + #ASHost
      ConString = ConString + " SYSNR=" + #SysNr
      ConString = ConString + " CLIENT=" + #Client
      ConString = ConString + " USER=" + #User
      ConString = ConString + " PASSWD=" + #PassWord
      ConString = ConString + " LANG=" + #Language
      ;ConString = ConString + " RFC_TRACE=1"
      ;ConString = ConString + " ABAP_DEBUG=1"
      ConString = ConString + #NULL$
      ProcedureReturn CallFunction(#RFCLib, "RfcOpenEx", @ConString, RfcErrorInfoEx)
    EndProcedure
  ; Procedure DisConnectSAP---------------------------------------------
    Procedure DisConnectSAP(hRFC.l)
      CallFunction(#RFCLib, "RfcClose", hRFC)
    EndProcedure
; End-------------------------------------------------------------------Code: Select all
; Begin-----------------------------------------------------------------
  Structure RFC_ERROR_INFO_EX
    group.l
    key.s{33}
    message.s{513}
  EndStructure
  Structure RFC_PARAMETER
    *name
    nlen.l
    type.l
    leng.l
    *addr
  EndStructure
  Structure RFC_TABLE
    *name
    nlen.l
    type.l
    leng.l
    ithandle.l
    itmode.l
    newitab.l
  EndStructure
  Structure RFCSI
    rfcproto.s{3}
    rfcchartyp.s{4}
    rfcinttyp.s{3}
    rfcflotyp.s{3}
    rfcdest.s{32}
    rfchost.s{8}
    rfcsysid.s{8}
    rfcdatabs.s{8}
    rfcdbhost.s{32}
    rfcdbsys.s{10}
    rfcsaprl.s{4}
    rfcmach.s{5}
    rfcopsys.s{10}
    rfctzone.s{6}
    rfcdayst.s{1}
    rfcipaddr.s{15}
    rfckernrl.s{4}
    rfchost2.s{32}
    rfcsi_resv.s{12}
    rfcipv6addr.s{45}
  EndStructure
; End-------------------------------------------------------------------Code: Select all
; Begin-----------------------------------------------------------------
  ; ABAP/4 data types---------------------------------------------------
    Enumeration
      #TYPC
      #TYPDATE
      #TYPP
      #TYPTIME
      #TYPX
      #TYPTABH
      #TYPNUM
      #TYPFLOAT
      #TYPINT
      #TYPINT2
      #TYPINT1
      ;#TYPW
      #TYP1 = 12
      #TYP2
      #TYPDECF16 = 23
      #TYPDECF34
    EndEnumeration
  ; RFC data types------------------------------------------------------
    Enumeration
      #RFCTYPE_CHAR = #TYPC
      #RFCTYPE_DATE = #TYPDATE
      #RFCTYPE_BCD = #TYPP
      #RFCTYPE_TIME = #TYPTIME
      #RFCTYPE_BYTE = #TYPX
      #RFCTYPE_ITAB = #TYPTABH
      #RFCTYPE_NUM = #TYPNUM
      #RFCTYPE_FLOAT= #TYPFLOAT
      #RFCTYPE_INT = #TYPINT
      #RFCTYPE_INT2 = #TYPINT2
      #RFCTYPE_INT1 = #TYPINT1
      #RFCTYPE_DATE_1 = #TYP1
      #RFCTYPE_DATE_2 = #TYP2
      #RFCTYPE_NULL
      #RFCTYPE_WIDE_2
      #RFCTYPE_WIDE_4
      #RFCTYPE_STRUCTURE
      #RFCTYPE_ABAP4OBJECT
      #RFCTYPE_IUNKNOWN
      #RFCTYPE_WSTRING
      #RFCTYPE_SAPAUTOMATION
      #RFCTYPE_STUB
      #RFCTYPE_WIRE_OBJECT
      #RFCTYPE_BLOB
      #RFCTYPE_CORBA_OBJECT
      #RFCTYPE_PADDING
      #RFCTYPE_UNICODE
      #RFCTYPE_XMLDATA
      #RFCTYPE_STRING
      #RFCTYPE_XSTRING
      #RFCTYPE_DECF16
      #RFCTYPE_DECF34
    EndEnumeration
  ; RFC return codes---------------------------------------------------
    Enumeration
      #RFC_OK                          ;O.K.
      #RFC_FAILURE                     ;Error occurred
      #RFC_EXCEPTION                   ;Exception raised
      #RFC_SYS_EXCEPTION               ;System exception raised
      #RFC_CALL                        ;Call received
      #RFC_INTERNAL_COM                ;Internal communication
      #RFC_CLOSED                      ;Connection closed
      #RFC_RETRY                       ;No Data yet
      #RFC_NO_TID                      ;No Transaction ID available
      #RFC_EXECUTED                    ;Function already executed
      #RFC_SYNCHRONIZE                 ;Synchronous Call in Progress
      #RFC_MEMORY_INSUFFICIENT         ;Memory insufficient
      #RFC_VERSION_MISMATCH            ;Version mismatch
      #RFC_NOT_FOUND                   ;Function Not found
      #RFC_CALL_NOT_SUPPORTED          ;This call is Not supported
      #RFC_NOT_OWNER                   ;Caller does Not own the handle
      #RFC_NOT_INITIALIZED             ;RFC Not yet initialized
      #RFC_SYSTEM_CALLED               ;A system call is executed
      #RFC_INVALID_HANDLE              ;Invalid handle passed to API
      #RFC_INVALID_PARAMETER           ;Invalid parameter passed to API
      #RFC_CANCELED                    ;RFC call canceled by user
      #RFC_CONVERSION                  ;Conversation error detected
      #RFC_INVALID_PROTOCOL            ;Received data has bad format
      #RFC_TIMEOUT
    EndEnumeration
  ; RFC error group-----------------------------------------------------
    Enumeration
      #RFC_ERROR_PROGRAM = 101         ;Error in RFC program
      #RFC_ERROR_COMMUNICATION         ;Error in network/communications
      #RFC_ERROR_LOGON_FAILURE         ;SAP logon error
      #RFC_ERROR_SYSTEM_FAILURE        ;SAP system exception raised
      #RFC_ERROR_APPLICATION_EXCEPTION ;Function module raised exception
      #RFC_ERROR_RESOURCE              ;Resource not available
      #RFC_ERROR_PROTOCOL              ;RFC protocol error
      #RFC_ERROR_INTERNAL              ;RFC internal error
      #RFC_ERROR_CANCELLED             ;RFC server was cancelled
      #RFC_ERROR_BUSY                  ;System is busy
    EndEnumeration
  ; RFC_ITMODE - mode how to pass internal table------------------------
    Enumeration
      #RFC_ITMODE_BYREFERENCE          ;Table is passed by reference
      #RFC_ITMODE_BYVALUE              ;Table is passed by value
      #RFC_ITMODE_KEEPALIVE            ;Table is passed by reference,
                                       ;but is kept alive after return
    EndEnumeration
; End-------------------------------------------------------------------

