    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Sharp as C</title>
        <link>https://members.accu.org/index.php/articles/828</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 17, #4 - Aug 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c95/">174</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-95/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+95/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Sharp as C</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 August 2005 05:00:00 +01:00 or Wed, 03 August 2005 05:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<div class="blockquote">
<blockquote class="blockquote">
<p>1:18 For in much wisdom is much grief: and he that increaseth
knowledge increaseth sorrow. KJV - Ecclesiastes</p>
</blockquote>
</div>
<p><span class="bold"><b>In the beginning was</b></span> &hellip; a
word.</p>
<p>And the word was &hellip; an algorithm!? Or should I say
al-khwarizm? What does wikipedia (<a href=
"http://en.wikipedia.org/wiki/Main_Page" target=
"_top">http://en.wikipedia.org/wiki/Main_Page</a>) say about the
term algorithm?</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;An algorithm (the word is derived from the name of the Persian
mathematician Al-Khwarizmi), is a finite set of well-defined
instructions for accomplishing some task which, given an initial
state, will terminate in a corresponding recognizable
end-state&quot;</p>
</blockquote>
</div>
<p>Al-Khwarizmi? Citing: &quot;<span class="quote">Abu Abdullah Muhammad
bin Musa al-Khwarizmi, was a Persian scientist, mathematician,
astronomer/astrologer, and author. He was probably born in 780, or
around 800; and probably died in 845, or around 840.</span>&quot;</p>
<p>1200 years!</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e43" id="d0e43"></a>What This
Article is About and How to Read This</h2>
</div>
<p>This article represents my own point of view at the general
approach to software development and its architecture. In respect
of your time, I'm going to hide all my thoughts I had and way I
did, whether they were short or long and going to offer you just a
final conclusions. Sometimes these conclusions might seem strange,
but that is what I'm thinking, my personal opinion. In this article
I'm doing nothing, but expressing my own point of view, does it
make any sense to you or not, do you see any useful ideas here or
think all is absolutely useless it is for you to decide.</p>
<p>The plan of the article is pretty simple: In 'How it should be'
section I'm describing the general idea. If you find it interesting
then going further in the section 'It is possible.' You will find
the details of the realization. Everything else is no more than
pros &amp; cons of that approach, proposed in the 'How it should
be.' section. If the idea, described in the 'How it should be'
section seems pointless to you, it might spare your time to read no
further.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e50" id="d0e50"></a>How Should It
Be</h2>
</div>
<div class="blockquote">
<blockquote class="blockquote">
<p>&quot;...since brevity is the soul of wit, And tediousness the limbs
and outward flourishes, I will be brief: your noble son is mad:&quot;
POLONIUS, Hamlet, Prince of Denmark, W. Shakespeare</p>
</blockquote>
</div>
<p>Whether it possible to draw an architecture of application in
general? Somebody might say it depends on business. In my opinion
it should look like Figure 1.</p>
<div class="figure"><a name="d0e58" id="d0e58"></a>
<div class="mediaobject c3"><img src="/var/uploads/journals/resources/Figure1.gif" align=
"middle"></div>
<p class="title c4">Figure 1. </p>
</div>
<p>Business logic is to be written in script to make it as plain as
possible. The business entities are whatsoever your business needs,
like collections (vectors, maps, sets, etc.), logging systems, DB
vendors (MSSQL, Oracle, SyBase, etc), IPC (DCOM, RPC, Sockets,
pipes), threading systems (such as POSIX) and so on. All these
entities should expose some kind of an plain interface which
basically are getters and setters. These entities should be as
simple in logic as possible and in general they should export
either data or simple functionality.</p>
<p>The business logic is written in some scripting language and
portable also. If some entity is going to be changed (you are
switching from SQL to Oracle for instance) the logic should not be
changed, in the perfect case.</p>
<p>What I'm trying to say here is that any business logic and
entities are to be separate. Let us see a classical sample:</p>
<p>int main() { printf (&quot;Hello world.\n&quot;); return 0; }</p>
<p>In this sample business logic is represented by means of C
script (in general this is a script, since we have no idea how we
are going to start it up) and business entities are only the one,
this is the C-library (libc, msvcrt for instance), exposing plain
'exported' C-functions (printf in our case), this is the interface
(see figure 2).</p>
<div class="figure"><a name="d0e73" id="d0e73"></a>
<div class="mediaobject c3"><img src="/var/uploads/journals/resources/Figure2.gif" align=
"middle"></div>
<p class="title c4">Figure 2. </p>
</div>
<p>This approach goes contrary with the traditional OOP approach of
development. Since OOP puts together an object and its
functionality, this approach does otherwise. It is even thus.
Keeping things clean and trying to save some time I would dare to
say that, OOP worked out its resource and it is &hellip; dead.</p>
<p>Now I'm saying that developing business entities is not as
painful as the development of business logic algorithms.
Construction of business algorithms is a much more peculiar,
painful, nervous process and takes much more time and resources
than anything else.</p>
<p>Therefore <span class="bold"><b>business logic is to be written
in plain script, and this script is to be changeable at run-time,
without any recompilation</b></span>. My basic objective is that
business logic should not be as a 'sacred ground',
once-working-never-changed. Its to be 'playable' whenever it is
required, especially on development/QA stages, <span class=
"bold"><b>this logic/script can be changed in run-time, with no any
commits/check-ins to be done, no rebuilding, no restarting, or any
other annoying procedures, just simple changing the script should
immediately impact the running system</b></span>. Let me guess, you
say impossible, or if it be possible - too complicated.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e90" id="d0e90"></a>It Is
Possible</h2>
</div>
<p>And it is not so complicated. This section will show how it
works. (The sample code is written for the Microsoft Windows
platform)</p>
<p>This is an application tree:</p>
<div class="literallayout">
<p>+--c_dispatcher<br>
+--Debug<br>
+--frontend_app<br>
+--include<br>
+--my_script<br>
+--my_script_c_proxy<br>
+--my_script_d_proxy</p>
</div>
<p>Inside the folder <tt class="filename">fronend_app</tt> is the
main (console) application. There is only one file there:
<tt class="filename">frontend_app.cpp</tt></p>
<pre class="programlisting">
// frontend_app.cpp
// (c) George Shagov, 2005
#include &lt;windows.h&gt;
#include &quot;..\\include\my_structs.h&quot;

typedef int (__cdecl *MYFARPROC)
            (int nArg,
             char* pString,
             SMyStructure* pMyStruct);

int main(int argc, char* argv[])
{

  HMODULE hMyScript = LoadLibrary
        (&quot;my_script_d_proxy.dll &quot;);
  MYFARPROC pProcSource = (MYFARPROC)
        GetProcAddress
        (hMyScript, &quot;c__my_entry_point&quot;);

  SMyStructure myStruct;

  myStruct.m_nVal = 0;
  strcpy(myStruct.m_sString, &quot;&quot;);
  /*
  * calling for entry point.
  * directly
  */
  char sMyString[32];
  strcpy(sMyString, &quot;My string here.&quot;);
  pProcSource(argc, sMyString, &amp;myStruct);

  return 0;
}
</pre>
<p>As you can see here, it gets an address of entry point of the
script and executes it.</p>
<pre class="programlisting">
The script itself might be found inside <tt class=
"filename">my_scipt</tt> folder, the file name: <tt class=
"filename">my_script.c_</tt>. There are some additional files there: <tt class="filename">my_script.gnrtd.c</tt> <tt class="filename">my_script.gnrtd.h</tt>, these ones are to be generated from <tt class="filename">my_script.c</tt> (below).

// my_script.c_
// (c) George Shagov, 2005

/*********************************************
*
* this file is automatically generated from 
* my_script.c_    do not modify it
*
*********************************************/
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &quot;..\\include\\my_structs.h&quot;
#include &quot;my_scri&quot;pt.gnrtd.h&quot;

int c__get_value_1_impl(char* pString)
{
  return 1;
}

int c__get_value_2_impl(int nArg)
{
  return 2;
}

int c__call_in_case_varables_are_equal_impl
    (SMyStructure* pMyStruct)
{
  pMyStruct-&gt;m_nVal = 0;
  strcpy(pMyStruct-&gt;m_sString, &quot;equal&quot;);
  return 0;
}

int c__call_in_case_varables_are_not_equal_impl
      (SMyStructure* pMyStruct)
{
  pMyStruct-&gt;m_nVal = 0;
  strcpy(pMyStruct-&gt;m_sString, &quot;not equal&quot;);
  return 0;
}

int c__re_entry_impl(int nArg, char* pString,
                     SMyStructure* pMyStruct)
{
  int nVar1 = c__get_value_1(pString);
  int nVar2 = c__get_value_2(nArg);

  if (nVar1 == nVar2)
  {
    c__call_in_case_varables_are_equal
          (pMyStruct);
  }
  else
  {
    c__call_in_case_varables_are_not_equal
         (pMyStruct);
  }

  return 11;
}

int c__my_entry_point_impl(int nArg,
      char* pString, SMyStructure* pMyStruct)
{
  int nRet;

  printf(&quot;------\nbefore:\n&quot;);
  printf(&quot;nArg: %d, string: %s\n&quot;, nArg,
        pString);
  printf(&quot;pMyStruct-&gt;m_nVal: %d, 
        pMyStruct-&gt;m_sString: %s\n&quot;, 
        pMyStruct-&gt;m_nVal, 
        pMyStruct-&gt;m_sString);

  nRet = c__re_entry(nArg, pString,
        pMyStruct);

  printf(&quot;++++++after:\n&quot;);
  printf(&quot;nArg: %d, string: %s\n&quot;, nArg,
        pString);
  printf(&quot;pMyStruct-&gt;m_nVal: %d, 
          pMyStruct-&gt;m_sString: %s\n&quot;,
          pMyStruct-&gt;m_nVal,
          pMyStruct-&gt;m_sString);
  printf(&quot;ret: %d\n-------\n&quot;, nRet);

  return nRet;
}
</pre>
<p><tt class="function">c__my_entry_point_impl</tt> is an entry
point to be called from <tt class="filename">frontend_app</tt>.
<tt class="filename">my_script.gnrtd.c</tt> is merely a copy of the
original script. <tt class="filename">my_script.gnrtd.h</tt>
represents the declarations.</p>
<p>As you can see <tt class="filename">fronend_app</tt> uses
<tt class="filename">my_script_d_proxy</tt> library in order to
make a call to <tt class=
"function">c__my_entry_point_impl</tt>.</p>
<p>There are two files under <tt class=
"filename">my_script_d_proxy</tt> folder <tt class=
"filename">my_script_d_proxy.gnrtd.c</tt> &amp; <tt class=
"filename">my_script_d_proxy.gnrtd.h</tt>, both these files are to
be generated from original script (<tt class=
"filename">my_script.c_</tt>) also. <tt class=
"filename">my_script_d_proxy.gnrtd.c</tt> contains plugs for all
the functions, written in the script, like this:</p>
<pre class="programlisting">
int c__re_entry_stub(int nESP, int nArg, 
    char* pString, SMyStructure* pMyStruct)
{
  void* pArgs = 0;
  int nSize = 0;
  _asm
  {
    push eax; /* saving eax */
    mov eax, ebp; /* ebp points out at the
          parameters (as known) */
    add eax, 8; /* now eax points out at the first
          argument, which is nESP*/
    mov pArgs, eax;
    add pArgs, 4; /* since first argument is esp,
          but we need real argument here */
    mov eax, nESP;
    sub eax, pArgs; /* eax now has a phisical size
          of the stack */
    shr eax, 2; /* eax/4 - eax now has an amount
          of arguments put in the stack */
    mov nSize, eax; /* saving that size */
    pop eax; /* restoring eax */
  }
  return g_pDispatcherEntry(&quot;c__re_entry&quot;,
        pArgs, nSize);
}

int c__re_entry(int nArg, char* pString,
    SMyStructure* pMyStruct)
{
  int nESP;
  _asm
  {
    mov nESP, esp;
  }
  return c__re_entry_stub(nESP, nArg, pString,
        pMyStruct);
}
</pre>
<p>The assembly code remembers the pointer to the first argument,
which was put in the stack, the count of argument in stack, and
delivers a call to <tt class="filename">c_dispatcher</tt> library,
which then exports the <tt class=
"function">g__c_dispatcher_entry_point</tt> function.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e178" id="d0e178"></a>The Code of
<tt class="filename">c_dispatcher.cpp</tt></h2>
</div>
<pre class="programlisting">
// c_dispatcher.cpp
// (c) George Shagov, 2005
#include &lt;stdio.h&gt;
#include &lt;windows.h&gt;
#include &quot;c_dispatcher.h&quot;

static HINSTANCE s_hCSource = NULL;
static HINSTANCE s_hProxy = NULL;
typedef int (__cdecl *MYFARPROC)();

MYFARPROC GetMyProcAddress(
    const char* pFunctionName)
{
  char pFile[128];
  char pFnName[128];
  sprintf(pFile, &quot;my_script.%s_impl.c_&quot;, 
        pFunctionName);
  sprintf(pFnName, &quot;%s_impl&quot;, pFunctionName);
  FILE* f = fopen(pFile, &quot;r&quot;);
  if (f)
  {
    fclose(f);
    return (MYFARPROC)GetProcAddress(s_hProxy,
          pFnName);
  }
  else
    return (MYFARPROC)GetProcAddress
          (s_hCSource, pFnName);
}

BOOL APIENTRY DllMain( HANDLE hModule,
                     DWORD ul_reason_for_call,
                     LPVOID lpReserved)
{
  switch (ul_reason_for_call)
  {
    case DLL_PROCESS_ATTACH:
      s_hCSource = LoadLibrary
            (&quot;my_script.dll&quot;);
      s_hProxy = LoadLibrary
            (&quot;my_script_c_proxy.dll&quot;);
    break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    break;
    case DLL_PROCESS_DETACH:
      FreeLibrary(s_hCSource);
      FreeLibrary(s_hProxy);
    break;
}
return TRUE;
}

// This is an example of an exported function.
C_DISPATCHER_API int g__c_dispatcher_entry_point(
    const char* pFunctionName, 
    const void* pArguments, 
    int nArgumentsCount)
{
MYFARPROC pProc = GetMyProcAddress(pFunctionName);
void* pStack = 0;
if (nArgumentsCount)
{
_asm
{
mov ecx, nArgumentsCount;
loop_start_01:
push 0;
loop loop_start_01;
mov pStack, esp;
}
memcpy(pStack, pArguments, nArgumentsCount*4);
int nRet = pProc();
_asm
{
mov ecx, nArgumentsCount;
loop_start_02:
pop eax;
loop loop_start_02;
}
return nRet;
}
else
return pProc();
}
</pre>
<p>As you can see here the case dispatcher has found a file
<tt class="filename">my_script.&lt;function_name_impl&gt;.c_</tt>
it delegates call <tt class="filename">my_script_c_proxy</tt>
library, otherwise it defaults to <tt class=
"filename">my_script.dll</tt>, where the compiled script code is
located. This actually is a substitution. Before the call it
simulates the stack, knowing the pointer at the original position
and its size, after the call - simple unwinding. Simple, right?</p>
<p><tt class="filename">my_script_c_proxy</tt> library contains
four files. (Here I should say, since we are going to change the
code at run-time we need some kind of a C-interpreter. I took
<span class="application">cint</span>. <span class=
"application">cint</span> is free C-interpreter, powerful enough
and very suitable for this demo, yet there are couple of issues
which means that some disadvantages in this demo implementation
will be closely connected to this particular interpreter.
<tt class="filename">G__clink.c</tt> <tt class=
"filename">G__clink.h</tt> - these files are generated from
<tt class="filename">my_script_d_proxy.gnrtd.h</tt> (<tt class=
"filename">my_script_d_proxy</tt> folder) by <span class=
"application">cint</span>, since <tt class="classname">cint</tt>
during interpretation should not call to the script functions, but
to stubs, implemented inside the <tt class=
"filename">my_script_d_proxy</tt> library, in order to be able to
re-implement any function we need, not the whole script. The rest
of the functions are to be called from <tt class=
"filename">my_script.dll</tt>. It's a little bit tricky. The file
<tt class="filename">my_script_c_proxy.gnrtd.c</tt> contains stubs
which look like this:</p>
<pre class="programlisting">
MY_SCRIPT_C_PROXY_API int 
c__my_entry_point_impl(int nArg, 
     char* pString, SMyStructure* pMyStruct)
{
  char tmp[128];
  int nRet;

  s__setup_cint();
  sprintf(tmp,&quot;c__my_entry_point_impl((int)%d,
     (void*)0x%08lx, (SMyStructure*)0x%08lx);&quot;,
     nArg, (int)pString,pMyStruct);
     nRet = G__calc(tmp).obj.i; /* Call Cint
      parser */ return nRet;
}
</pre>
<p><tt class="function">G__calc</tt> is a <span class=
"application">cint</span> function, which make a call to the
script.</p>
<p>Well, actually, that's it.</p>
<p>Let us see how it works.</p>
<p>The context of <tt class="filename">c_\Debug</tt> folder (after
getting the project built) looks like this:</p>
<pre class="screen">
C_dispatcher.dll 
frontend_app.exe
my_script.dll
my_script_c_proxy.dll
my_script_d_proxy.dll
</pre>
<p>Starting the application we get:</p>
<pre class="screen">
before:
nArg: 1, string: My string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString:
++++++after:
nArg: 1, string: My string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString: not equal
ret: 11
-------
</pre>
<p>This is what produced by the compiled script, and now located in
the <tt class="filename">m_script.dll</tt> library.</p>
<p>In Debug folder we are creating an empty file: <tt class=
"filename">my_script.c__get_value_1_impl.c_</tt>. The existence of
this file will be a sign to the dispatcher that there is a
substitution for the <tt class="filename">c__get_value_1_impl</tt>
function. We should create the <tt class="filename">my_script.c_
file</tt> also, within the next content: (the presence of two files
is that disadvantage I referred to earlier caused by <span class=
"application">cint</span>).</p>
<pre class="programlisting">
// my_script.cpp : Defines the entry point for the DLL application.
//

#include &lt;stdio.h&gt;
#include &quot;..\\include\\my_structs.h&quot;

int c__get_value_1_impl(char* pString)
{
  pString[1] = 'X'; 
  printf(&quot;c__get_value_1 ==&gt;&gt; str: %s\n&quot;,
        pString);
  return 2;
}
</pre>
<p>The contents of the Debug folder looks like this:</p>
<pre class="screen">
C_dispatcher.dll
frontend_app.exe
my_script.c_ 
my_script.c__re_entry_impl.c_
my_script.dll
my_script_c_proxy.dll
my_script_d_proxy.dll
</pre>
<p>Restarting application gives the result:</p>
<pre class="screen">
------
before:
nArg: 1, string: My string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString:
c__get_value_1 ==&gt;&gt; str: MX string here.
++++++after:
nArg: 1, string: MX string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString: equal
ret: 11
-------
</pre>
<p>Now let us try to re-implement two functions. For this purpose
we are creating the second file: <tt class=
"filename">my_script.c__re_entry_impl.c_</tt>, in order to
signalize the dispatcher, and modifying the script.</p>
<pre class="programlisting">
// my_script.cpp : Defines the entry point for // the DLL application.
#include &lt;stdio.h&gt;
#include &quot;..\\include\\my_structs.h&quot;

int c__get_value_1_impl(char* pString)
{
  pString[1] = 'X'; 
  printf(&quot;c__get_value_1 ==&gt;&gt; str: %s\n&quot;,]
        pString);
  return 2;
}

int c__re_entry_impl(int nArg, char* pString,
    SMyStructure* pMyStruct)
{
  printf(&quot;\&quot;I'll not be juggled with.\nTo
      hell, allegiance! Vows, to the
      blackest devil!\nConscience and grace,
      to the profoundest pit!\nI dare
      damnation. To this point I stand,\&quot;\n&quot;);
  printf(&quot;...for this is script\n&quot;);

  int nVar1 = c__get_value_1(pString);
  int nVar2 = c__get_value_2(nArg);

  if (nVar1 == nVar2)
  {
    c__call_in_case_varables_are_equal
          (pMyStruct);
  }
  else
  {
    c__call_in_case_varables_are_not_equal
          (pMyStruct);
  }

  return 11;
}
</pre>
<pre class="screen">
The result:
------
before:
nArg: 1, string: My string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString:
&quot;I'll not be juggled with.
To hell, allegiance! Vows, to the blackest devil!
Conscience and grace, to the profoundest pit!
I dare damnation. To this point I stand,&quot;
...for this is script
c__get_value_1 ==&gt;&gt; str: MX string here.
++++++after:
nArg: 1, string: MX string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString: equal
ret: 11
-------
</pre>
<p>Now a little bit about parameters or arguments of the functions.
I might see already that the string 'My string here' has been
changed to 'MX string here', It has been done by means of
<tt class="function">c__get_value_1_impl</tt> and re-implemented in
the script. We are able to do the same with structures. Creating a
new file: <tt class=
"filename">my_script.c__call_in_case_varables_are_equal_impl.c_</tt>
and adding next function to the script:</p>
<pre class="programlisting">
int c__call_in_case_varables_are_equal_impl(
    SMyStructure* pMyStruct)
{
  pMyStruct-&gt;m_nVal = 0;
  strcpy(pMyStruct-&gt;m_sString, &quot;- EQUAL -&quot;);
  return 0;
}
</pre>
<pre class="screen">
The result:
------
before:
nArg: 1, string: My string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString:
&quot;I'll not be juggled with.
To hell, allegiance! Vows, to the blackest devil!
Conscience and grace, to the profoundest pit!
I dare damnation. To this point I stand,&quot;
...for this is script
c__get_value_1 ==&gt;&gt; str: MX string here.
++++++after:
nArg: 1, string: MX string here.
pMyStruct-&gt;m_nVal: 0, pMyStruct-&gt;m_sString: - EQUAL -
ret: 11
-------
</pre>
<p>By now the contents of the Debug folder looks like this:</p>
<pre class="screen">
c_dispatcher.dll
frontend_app.exe
my_script.c_ 
my_script.c__call_in_case_varables_are_equal_impl.c_
my_script.c__get_value_1_impl.c_
my_script.c__re_entry_impl.c_
my_script.dll
my_script_c_proxy.dll
my_script_d_proxy.dll
</pre>
<p>It works. As you can see:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>It is possible to change (or rather to say substitute) the code
(script) on run-time, no recompilation required.</p>
</li>
<li>
<p>It is not a hard task.</p>
</li>
</ol>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e320" id=
"d0e320"></a>Performance</h2>
</div>
<p>Yes of course using script instead of native code does mean
significant loss of performance, yet there are two things to
say:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>In the systems where performance is a key point (such as
real-time systems), no substitution is to be allowed. It means
there should not be any dispatcher library and all the calls to be
compiled as direct ones and linked during the compilation. In this
approach there will not be any losing of performance. Yet in
development for QA where possibility for substitution is highly
required but performance does not play a significant role, this
approach will be applicable.</p>
</li>
<li>
<p>In general, performance is not a key point. In this case If we
need substitution right in production. It is possible to do that
without significant lose of performance. In order to do that we
should:</p>
</li>
</ul>
</div>
<div class="orderedlist">
<ol type="1">
<li>
<p>Create and compile a separate library, let it have a name
<tt class="filename">my_script_subst.dll</tt>. This library would
contain the re-implementation of these functions which we need to
substitute.</p>
</li>
<li>
<p>Create and compile an additional proxy library, let it have a
name <tt class="filename">my_script_s_prioxy.dll</tt> which should
look like <tt class="filename">my_script_c_prioxy.dll</tt>, save
that all the calls will be delegated not to <span class=
"application">cint</span>, but to <tt class=
"filename">my_scipt_subst.dll</tt> (see step 1)</p>
</li>
<li>
<p>Modify the dispatcher so that it should know what <tt class=
"filename">my_script_s_prioxy.dll</tt> is.</p>
</li>
</ol>
</div>
<p>I didn't do that just in order not to overload the code. If the
basic idea is understandable, the rest is but technique.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e362" id="d0e362"></a>Cons and
Pros</h2>
</div>
<p>Had I patience and time I would write a book here, or two. Yet
in brief.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e367" id=
"d0e367"></a>Disadvantages</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The build procedure becomes more complicated, additional parsing
is required.</p>
</li>
<li>
<p>There should be an interpreter supplied</p>
</li>
<li>
<p>Read the performance section</p>
</li>
<li>
<p>Using C as a script might cause some problems, since C, by
default, has a direct access to memory and has no mechanism of
automatic unwinding, which may potentially cause leaks. Yet, that
should be a C-script, not C, it means that all functions which uses
access to memory should be exposed as entities.</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e383" id="d0e383"></a>Benefits</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Clarity. OOP code is much less readable than plain script and
this clarity is the main goal.</p>
</li>
<li>
<p>Ability to change the business logic run-time.</p>
</li>
<li>
<p>Control. Just think what we able to do having all entry-points
in our hands.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e396" id="d0e396"></a>TODO</h2>
</div>
<p>A lot.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>There should be a suitable C-interpreter</p>
</li>
<li>
<p>Parsing procedure</p>
</li>
<li>
<p>See the second clause described in the 'Performance' section</p>
</li>
<li>
<p>Dispatcher. Yes of cause the way it is implemented is not
applicable to real system. There should be a map of functions which
is to be updated in separate thread, according to timestamp of the
modification</p>
</li>
<li>
<p>And so on&hellip;</p>
</li>
</ul>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
