Login
`
Templates, Tools and Utilities
|
||
Add a comment to an Icetips ArticlePlease add your comments to this article.
Please note that you must provide both a name and a valid email address in order
for us to publish your comment. Comments are moderated and are not visible until they have been approved. Spam is never approved!
Back to article list Search Articles Add Comment Printer friendly Direct link 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.
Today is November 23, 2024, 2:03 am This article has been viewed 35358 times.
|
|