Skip to Content
avatar image
Former Member

Exchanging itabs between C and ABAP using RFC

Hello,

how can I send an internal table from ABAP to a C or C++ client, modify it here and send that modified table back to ABAP?

Thx for your help!

Thomas

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Nov 30, 2007 at 02:11 PM

    You need the SDK to do the C/C++ side and connectivity to SAP. On the SAP side, you create an RFC enabled function module, and use the TABLES parameters. The structure of the tables must be defined in the data dictionary. The tables are "changing" parameters, so you can either modify the one passed over, or you could have an input table and an output table.

    Don't use table types as IMPORTING and EXPORTING parameters in RFC function modules - it can cause severe problems.

    Within your ABAP program, you just call the RFC enabled function module.

    matt

    Add comment
    10|10000 characters needed characters exceeded

    • Former Member Former Member

      Here is my coding. Does anybody have an idea why the pointer in line 151 is = NULL ?

      Thx

      Tom

      #include <stdio.h>

      #include <stdlib.h>

      #include <string.h>

      #include <saprfc.h>

      #include <sapitab.h>

      static RFC_RC remote_function (RFC_HANDLE handle);

      static RFC_RC install (RFC_HANDLE handle);

      RFC_HANDLE handle;

      typedef struct RFCSTRUCT {

      RFC_INT seq;

      RFC_FLOAT m;

      RFC_FLOAT si;

      RFC_FLOAT sl;

      RFC_INT id;

      RFC_INT lo;

      RFC_FLOAT re;

      } rfcstruct;

      static RFC_TYPEHANDLE handleRFCSTRUCT;

      static RFC_TYPE_ELEMENT typeRFCSTRUCT[] = {

      /* name / / type / / length / / decimals */

      { "SEQ", TYPINT, sizeof(RFC_INT), 0 },

      { "M", TYPFLOAT, sizeof(double), 16 },

      { "SI", TYPFLOAT, sizeof(double), 16 },

      { "SL", TYPFLOAT, sizeof(double), 16 },

      { "ID", TYPINT, sizeof(RFC_INT), 0 },

      { "LO", TYPINT, sizeof(RFC_INT), 0 },

      { "RE", TYPFLOAT, sizeof(double), 16 },

      };

      #define ENTRIES( tab ) ( sizeofR(tab)/sizeofR((tab)[0]) )

      /****************************************

      • Main

      ****************************************/

      int main (int argc, char ** argv)

      {

      RFC_RC rc;

      handle = RfcAccept(argv);

      rc = install(handle);

      if (rc != RFC_OK)

      {

      RfcAbort(handle,"Initialization error");

      return(1); }

      do{

      rc = RfcDispatch(handle);

      } while (rc == RFC_OK);

      RfcClose(handle);

      return(0); }

      /****************************************

      • install()

      ****************************************/

      static RFC_RC install(RFC_HANDLE handle) {

      RFC_RC rfc_rc;

      rfc_rc = RfcInstallFunctionExt( handle,

      "FUNC",

      (RFC_ONCALL)remote_function,

      "nodocu" );

      if (rfc_rc != RFC_OK)

      return rfc_rc;

      return RFC_OK;

      }

      /******************************************

      • remote function

      *******************************************/

      static RFC_RC remote_function (RFC_HANDLE handle) {

      RFC_RC rfc_rc;

      ITAB_H itab_handle;

      RFC_PARAMETER Exporting[0];

      RFC_PARAMETER Importing[0];

      RFC_TABLE Table[1];

      Exporting[0].name = NULL;

      Importing[0].name = NULL;

      rfc_rc = RfcInstallStructure( "rfcstruct",

      typeRFCSTRUCT,

      ENTRIES(typeRFCSTRUCT),

      &handleRFCSTRUCT);

      itab_handle = ItCreate("ITAB", sizeof(rfcstruct), 0, 0);

      Table[0].name = "ITAB";

      Table[0].nlen = strlen("ITAB");

      Table[0].type = handleRFCSTRUCT;

      Table[0].leng = sizeof(rfcstruct);

      Table[0].itmode = RFC_ITMODE_BYREFERENCE;

      Table[0].ithandle = itab_handle;

      Table[1].name = NULL;

      rfc_rc = RfcGetData(handle, Importing, Table);

      if (rfc_rc != RFC_OK)

      return (rfc_rc);

      modify_table(itab_handle, handle);

      rfc_rc = RfcSendData(handle, Exporting, Table);

      return(rfc_rc);

      ItFree(itab_handle);

      RfcClose(handle);

      }

      /******************************************

      • modity itab...

      *******************************************/

      modify_table(ITAB_H itab_handle, RFC_HANDLE handle) {

      int linenr;

      int lineleng;

      char table_data[8192];

      struct RFCSTRUCT *ptr=NULL;

      RFC_FLOAT a;

      RFC_FLOAT s;

      RFC_FLOAT sl;

      RFC_INT id;

      RFC_INT lo;

      lineleng = ItLeng(itab_handle);

      for (linenr = 1; ; linenr++)

      {

      ptr = ( struct RFCSTRUCT *) ItGetLine(itab_handle, linenr);

      /* HERE: POINTER IS ALWAYS == NULL - WHAT'S WRONG ??? */

      if (ptr == NULL) break;

      memcpy(table_data, ptr, lineleng);

      }

      return; }

  • Nov 30, 2007 at 04:13 PM

    First make sure you have rfc destination defined in sap between sap and c, c++.

    You can actually exchange a structure with one big line or internal table in any format but the internal table format should be same in both systems.

    From sap side, you can get that using call function 'zdfd' destination 'dest name'.

    Add comment
    10|10000 characters needed characters exceeded

  • avatar image
    Former Member
    Dec 05, 2007 at 02:15 PM

    Hi,

    I believe I fixed the bug: Make sure that your pointer is of type char. In order to read or update fields of a table row, use memcpy. Add sizeof(datatype current element) to the ptr.

    That works in my case!

    Thomas

    Add comment
    10|10000 characters needed characters exceeded