2007 Nov 30 1:42 PM
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
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
2007 Nov 30 2: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
2007 Nov 30 2:20 PM
Must I transfer the itab using "CHANGING" or "TABLES" statement in ABAP?
Must I call ItCreate in C in that case (I'm actually just receiving an itab in C)?
Tom
2007 Nov 30 3:00 PM
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; }
2007 Nov 30 4: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'.
2007 Dec 05 2: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
| User | Count |
|---|---|
| 4 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |