` Printed Icetips Article

Icetips Article



Par2: C Programming in Clarion
1998-05-18 -- Sean Wilson
 
The Clarion development system has been shipping with a C compiler for some time and 
yet many people are still running into problems developing Multi-Language applications. 
 The Programmer's Guide contains a single chapter on Multi-Language Programming 
which is a must read, despite the fact that it was written about 5 years ago and some of 
the information is no longer accurate or relevant. 
 Multi-Language Programming deserves a detailed discussion, however this article is 
intended only to illustrate the most fundamental aspects of calling C code from a Clarion

application. 
 Those of you that use the Application Generator for developing every application will 
have to excuse the fact that I'm an unrepentant hand-coder. 

The Anatomy of a C++ Source File 

Those of you who are still conscious are probably saying "C++, why would I want to 
know about C++? I want to call C code!" The problem is that the 'C' compiler that 
ships with Clarion is really a C++ compiler. It does the same job, but there are some 
important differences, I won't go into all the subtle differences between C & C++, I will

simply discuss those that are likely to affect the way you have to code for compatibility
with Clarion. 
 The best way to examine a programming issue is to look at some code: 


 1: // TSTC.C
 2: #if defined(__cplusplus)
 3: extern "C" {
 4: #endif
 5: int add(int a, int b);
 6: #if defined(__cplusplus)
 7: };
 8: #endif
 9:
10: int add(int a, int b)
11: { return a+b;
12: }
This possibly looks a little more complicated than you first anticipated, I will now 
describe in detail what is going on at each line of code: 

1 C++ line comments begin with '//', the comment is simply to tell you what the C file 
in this example is called. 
2 This introduces a section of conditionally compiled code. The __cplusplus macro is 
defined whenever a C++ compiler is being used to compile the code. 
3 The extern "C" directive is used to declare a name that will use C language naming 
conventions. By default C++ compilers mangle or decorate names by encoding 
additional type information into the name to facilitate type-safe linking. This directive
will disable the name-mangling and prefix the name with an underscore ('_'). 
4 This terminates a section of conditionally compiled code. 
5 The prototype for the C function. As it appears within the extern "C" directive the 
linkage name generated byt the compiler will be "_add". 
7 This terminates the extern "C" directive. 
10-12 The definition of the C function. Note that C++ compilers require ANSI syntax
which expects the definition to be fully prototyped with the parameter types included 
in the parameter list. 


Calling C From Clarion 

The Clarion code is simpler to explain, particularly as you are probably quite familiar
with
the language, still taking a similar approach: 
 1:! TSTCLW.CLW  
 2:  PROGRAM
 3:
 4:  MAP
 5:    MODULE('TstC')
 6:      add(SIGNED a, SIGNED b), SIGNED, PROC, RAW, NAME('_add')
 7:    END
 8:  END
 9:
10:  CODE
11:  MESSAGE(add(2,2))
This code does very little, in fact nothing useful other than to demonstrate the success 
of calling the add() function by displaying its' result. 

5 The MODULE() statement is required to prototype externally defined procedures, 
however the name that appears is not used. 
6 This is where the hard work is done. Note that the prototype should match exactly 
the C++ prototype otherwise some very odd problems will occur. Parameter prototyping 
errors are usually very difficult to track down. The NAME() attribute should contain the 
linkage name for the function which as noted before is "_add". Although it is not 
required for this function, it is good practice to include the RAW attribute which
ensures
that additional type iformation is not passed as an additional implicit parameter. I
usually 
like to include the PROC attribute which suppresses warnings when functions are 
called as procedures.  


Putting it all Together 

The only thing missing is the project file, this couldn't be simpler and is easily created
in 
the Clarion IDE. I have included it here for completeness but it deserves no additional 
explanation: 
-- tstc
#noedit
#system win32
#model clarion dll
#pragma debug(vid=>full)
#compile tstclw.clw
#compile tstc.c
#link tstc.exe


And Finally... 

That's it! Nothing simpler really, however I realise I have only scratched the surface 
here. If there are specific issues that you would like to see addressed then let me know,
I will gladly incorporate new information into future articles.



Printed May 5, 2024, 10:50 am
This article has been viewed/printed 35138 times.