mirror of
https://github.com/EiffelSoftware/eiffel-org.git
synced 2025-12-07 15:22:31 +01:00
Date:2012-12-14T00:21:39.000000Z git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@1207 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
67 lines
5.1 KiB
Plaintext
67 lines
5.1 KiB
Plaintext
[[Property:title|Interfacing with C and C++]]
|
|
[[Property:weight|0]]
|
|
[[Property:uuid|dcc4e216-307b-46ec-1bc1-a15da8b99469]]
|
|
{{UnderConstruction}}
|
|
|
|
|
|
Interfacing with C and C++ are similar enough that both can be covered together. There are two basic mechanisms available. The first and simpler of the two uses an existing routine and is available only to C externals. Using this approach you simply specify the '''signature''' of an existing C function along with where the function can be found. The second mechanism allows you to write C or C++ code inline. The second option is always recognizable by the presence of the word "'''inline'''" in the external specification. Again, the '''inline''' option is the only one allowed for C++ externals.
|
|
|
|
==Using an existing C function==
|
|
|
|
Here is an example of an external targeting an existing C function. In this case it's the <code>floor</code> function from the C library.
|
|
|
|
<code>
|
|
floor (v: DOUBLE): DOUBLE
|
|
-- Floor of `v'
|
|
external
|
|
"C signature (double): double use <math.h>"
|
|
end
|
|
</code>
|
|
|
|
The Eiffel external function <code>floor</code> now gives Eiffel code access to the C library function of the same name.
|
|
|
|
Here <code>external</code> is an Eiffel keyword that introduces the external specification that appears in the quoted string that follows. (The quoted string is actually an Eiffel [[ET: Other mechanisms|manifest string]], so it could actually be a simple quoted string or a [[ET: Other mechanisms|verbatim string]].) Within the quoted string we find first the registered language designator, in this case "C", followed by the function's signature, followed by the location in which the C function can be found. The terms "signature" and "use" within the quoted string are technically not Eiffel language keywords, but are keywords used in the specification of externals. There is one other similar keyword "inline" which can be used, but we will address it later.
|
|
|
|
The "signature" consists of the types of the arguments to C function as well as the function's return type. The argument types are separated by commas in a list enclosed in parentheses. A colon precedes the function type. In cases in which the target function takes no arguments, it is not necessary to include a set of empty parentheses in the signature. However, for compatibility purposes, the empty parentheses are allowed.
|
|
|
|
The "use" part denotes provides a file name or list of file names. File names can be either "user" file names or "system" file names. In the case of our example, a system file name "<code><math.h></code>" is used. System files are those that should be found by the system with no additional information. System file names are enclosed in angle brackets. User file names are included in a quoted string. User file names will be passed as written to the operating system. Remember that when coding a user file name, that because it already occurs within a quoted string, you must use the percent sign to code the quotation marks inside a quoted string, for example:
|
|
|
|
<code>
|
|
"C signature (double): double use %"my_c_header.h%""
|
|
</code>
|
|
|
|
Alternatively, you could code the external as a verbatim string. This would make the percent signs unnecessary.
|
|
|
|
There's one more thing to note about using existing C functions. In the <code>floor</code> example above, the Eiffel function has the same name as the C function it targets. But that may not always be the case. It's possible that the C function name might conflict with a name already established in your class, or might conflict with Eiffel naming conventions. Suppose you wanted to call the Eiffel routine <code>my_floor</code> instead of <code>floor</code>. You could use the <code>alias</code> part of the external specification to state that the actual C function name differs from the Eiffel name, as shown below.
|
|
|
|
<code>
|
|
my_floor (v: DOUBLE): DOUBLE
|
|
-- Floor of `v'
|
|
external
|
|
"C signature (double): double use <math.h>"
|
|
alias
|
|
"floor"
|
|
end
|
|
</code>
|
|
|
|
|
|
==Inline externals==
|
|
|
|
In addition to using an existing C function, you can, for both C and C++, create an '''inline''' external. The idea here is that you write the necessary C or C++ language within the definition of the external. In the case of inline externals the <code>alias</code> part is used to contain the inline code rather than a function name. Your inline C and C++ code can access the arguments of the external feature. Let's look at <code>my_floor</code> written as an inline external:
|
|
|
|
<code>
|
|
my_floor (v: DOUBLE): DOUBLE
|
|
-- Floor of `v'
|
|
external
|
|
"C inline use <math.h>"
|
|
|
|
alias
|
|
"return floor($v)"
|
|
end
|
|
</code>
|
|
|
|
In the <code>alias</code> part you see a line of C code calling the library function <code>floor</code> and returning the result. The argument to the call to <code>floor</code> needs to be the argument to the Eiffel function <code>my_floor</code>. To do this in the inline C code, the dollar sign ('$') precedes the argument name "v". So, the convention in inline externals is to use the dollar sign in C or C++ code to reference an argument of the Eiffel function.
|
|
|
|
|
|
|