Skip to Content
Technical Articles
Author's profile photo Stefan Schnell

How to use C code via FBSL inside ABAP

Freestyle BASIC Script Language (FBSL), which is unfortunately not longer available, integrates a dynamic C JIT compiler, so is it possible to use ANSI C code inside FBSL.

Here an example how to use ANSI C inside ABAP.


"-Begin-----------------------------------------------------------------
  Program zCMandelbrot.

    "-Constants---------------------------------------------------------
      Constants CrLf(2) Type c Value %_CR_LF.
      Constants SW_SHOWNORMAL Type i Value 1.
      Constants FbslFileName Type String Value 'zCMandelbrot.fbs'.

    "-Variables---------------------------------------------------------
      Data oFBSL Type OLE2_OBJECT.
      Data Buffer Type String Value ''.
      Data WorkDir Type String Value ''.
      Data WinInc Type String Value ''.
      Data FileName Type String Value ''.
      Data ProcID Type i Value 0.
      Data rc Type i.

    "-Macros------------------------------------------------------------
      Define _.
        Concatenate Buffer &1 CrLf Into Buffer.
      End-Of-Definition.

      Define Flush.
        Call Function 'AC_SYSTEM_FLUSH' Exceptions Others = 1.
      End-Of-Definition.

    "-Main--------------------------------------------------------------
      Create Object oFBSL 'ScriptX'.
      Check sy-subrc = 0 Or  oFBSL-Handle = 0 Or oFBSL-Type  'OLE2'.

      Call Method Of oFBSL 'About'.

      Call Method cl_gui_frontend_services=>get_sapgui_workdir
        Changing SAPWORKDIR = WorkDir Exceptions Others = 1.

      Call Method Of oFBSL 'ExtractFbslExe'.

"-FBSL script begin-----------------------------------------------------
_ 'Dim MaxIter = 50'.
_ 'Dim XRes As Integer'.
_ 'Dim YRes As Integer'.
_ 'Dim colors[MaxIter] As Integer'.

_ 'FBSLSETTEXT(Me, "DynC Mandelbrot Benchmark")'.
_ 'RESIZE(Me, 0, 0, 400, 400)'.
_ 'SHOW(Me)'.

_ 'FillColorTable()'.
_ 'FBSL.GETCLIENTRECT(ME, 0, 0, XRes, YRes)'.

_ 'Dim hdc = GetDC(ME)'.
_ 'Dim t = GetTickCount()'.

_ 'GenMandelbrot(-2.1, -1.25, 0.6, 1.25, XRes, YRes, MaxIter, hDC, _'.
_ '  @colors[0])'.

_ 'MSGBOX(, GetTickCount() - t & " ticks", "FBSL",)'.
_ 'ReleaseDC(ME, hdc)'.

  "-Dynamic C routine begin---------------------------------------------
_ 'DynC GenMandelbrot(!!xMn, !!yMn, !!xMx, !!yMx, %xr, %yr, %mitrs, _'.
_ '  %dc, %clr)'.

    "-ANSI C begin------------------------------------------------------
    "-
    "- You can store this code block in an include
    "-
    "-------------------------------------------------------------------

_ '  void __attribute__((stdcall)) SetPixel(int, int, int, int);'.

_ '  int Iterate(double cx, double cy, int MaxIter)'.
_ '  {'.
_ '    int iters = 0;'.
_ '    double X = cx, Y = cy, X2 = X * X, Y2 = Y * Y;'.
_ '    double temp;'.

_ '    while (iters++ < MaxIter && X2 + Y2 < 4) {'.
_ '      temp = cx + X2 - Y2;'.
_ '      Y = cy + 2 * X * Y;'.
_ '      Y2 = Y * Y;'.
_ '      X = temp;'.
_ '      X2 = X * X;'.
_ '    }'.

_ '    return iters;'.
_ '  }'.

_ '  void main(double xMn, double yMn, double xMx, double yMx, '.
_ '    int XRes, int YRes, int MaxIter, int hDC, int* colors[])'.
_ '  {'.
_ '    int iX, iY, iters;'.
_ '    double cx, cy;'.
_ '    double dx = (xMx - xMn) / (XRes - 1);'.
_ '    double dy = (yMx - yMn) / (YRes - 1);'.

_ '    for (iY = 0; iY < YRes; iY++) {'.
_ '      cy = yMn + iY * dy;'.
_ '      for (iX = 0; iX < XRes; iX++) {'.
_ '        cx = xMn + iX * dx;'.
_ '        iters = Iterate(cx, cy, MaxIter);'.
_ '        if (iters == MaxIter)'.
_ '          SetPixel(hDC, iX, iY, 0);'.
_ '        else'.
_ '          SetPixel(hDC, iX, iY, (int)colors[iters]);'.
_ '      }'.
_ '    }'.

_ '  }'.

    "-ANSI C end--------------------------------------------------------

_ 'End DynC'.
  "-Dynamic C routine end-----------------------------------------------

_ 'SUB FillColorTable()'.
_ '  DIM r, g, b'.
_ '  DIM rd, gd, bd'.
_ '  DIM rr, gg, bb'.
_ '  DIM i, j, wid'.

_ '  DIM clr[3]'.
_ '  clr[1] = RGB(0, 255, 0)'.
_ '  clr[2] = RGB(255, 255, 0)'.
_ '  clr[3] = RGB(255, 0, 0)'.

_ '  wid = MaxIter / 3'.

_ '  FOR j = 0 TO 2'.
_ '    toRGB(clr[j], r, g, b)'.
_ '    toRGB(clr[j + 1], rr, gg, bb)'.
_ '    rd = (rr - r) / (wid + 1)'.
_ '    gd = (gg - g) / (wid + 1)'.
_ '    bd = (bb - b) / (wid + 1)'.
_ '    FOR i = 0 TO wid'.
_ '      colors[j * wid + i] = RGB(r, g, b)'.
_ '      r = r + rd'.
_ '      g = g + gd'.
_ '      b = b + bd'.
_ '    NEXT'.
_ '  NEXT'.
_ 'END SUB'.

_ 'SUB toRGB(c, r, g, b)'.
_ '  r = c BAND &HFF'.
_ '  g = (c BAND &HFF00) / &H100'.
_ '  b = (c BAND &HFF0000) / &H10000'.
_ 'END SUB'.

"-FBSL script end-------------------------------------------------------

      Concatenate WorkDir '\' FbslFileName Into FileName.
      Call Method Of oFBSL 'WriteFile' Exporting #1 = FileName
        #2 = Buffer.
      Flush.

      Call Method Of oFBSL 'Shell' = ProcID Exporting
        #1 = 'Fbsl.exe' #2 = FbslFileName #3 = SW_SHOWNORMAL #4 = 1.
      Flush.

      Call Method Of oFBSL 'DeleteFile' Exporting #1 = FileName.
      Call Method Of oFBSL 'DeleteFile' Exporting #1 = 'Fbsl.exe'.

      Free Object oFBSL.

"-End-------------------------------------------------------------------

 

 

zCMandelbrot.abap.jpg

You can store your C code in an include file and on this way you have an own C style code block inside your ABAP code.

In the message box you see the count of ticks (484) to generate the mandelbrot graphic. If you use the FBSL program, you need more ticks (2752).

Have fun with your polyglot ABAP programs.

Cheers
Stefan

Assigned tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Hai Wang
      Hai Wang

      WOW! How do you find it?!! 😯

      Author's profile photo Stefan Schnell
      Stefan Schnell
      Blog Post Author

      Hello Hai,

      thanks for your reply. My idea is to combine the functions of the presentation and the application server. FBSL is an excellent platform, as you can see.

      Cheers

      Stefan