Call a foreign-language function: Difference between revisions
Content added Content deleted
(→{{header|Lisaac}}: Explain backtick notation) |
(→{{header|Ada}}: added C++) |
||
Line 30: | Line 30: | ||
Free (S2); |
Free (S2); |
||
end Test_C_Interface; |
end Test_C_Interface; |
||
</lang> |
|||
=={{header|C++}}== |
|||
While calling C functions from C++ is generally almost trivial, <code>strdup</code> illustrates some fine point in communicating with C libraries. However, to illustrate how to generally use C functions, a C function <code>strdup1</code> is used, which is assumed to have the same interface and behaviour as strdup, but cannot be found in a standard header. |
|||
In addition, this code demonstrates a call to a FORTRAN function defined as |
|||
<lang fortran> |
|||
FUNCTION MULTIPLY(X, Y) |
|||
DOUBLE PRECISION MULTIPLY, X, Y |
|||
</lang> |
|||
Note that the calling convention of FORTRAN depends on the system and the used FORTRAN compiler, and sometimes even on the command line options used for the compiler; here, GNU Fortran with no options is assumed. |
|||
<lang cpp> |
|||
#include <cstdlib> // for C memory management |
|||
#include <string> // for C++ strings |
|||
#include <iostream> // for output |
|||
// C functions must be defined extern "C" |
|||
extern "C" char* strdup1(char const*); |
|||
// Fortran functions must also be defined extern "C" to prevent name |
|||
// mangling; in addition, all fortran names are converted to lowercase |
|||
// and get an undescore appended. Fortran takes all arguments by |
|||
// reference, which translates to pointers in C and C++ (C++ |
|||
// references generally work, too, but that may depend on the C++ |
|||
// compiler) |
|||
extern "C" double multiply_(double* x, double* y); |
|||
// to simplify the use and reduce the probability of errors, a simple |
|||
// inline forwarder like this can be used: |
|||
inline double multiply(double x, double y) |
|||
{ |
|||
return multiply_(&x, &y); |
|||
} |
|||
int main() |
|||
{ |
|||
std::string msg = "The product of 3 and 5 is "; |
|||
// call to C function (note that this should not be assigned |
|||
// directly to a C++ string, because strdup1 allocates memory, and |
|||
// we would leak the memory if we wouldn't save the pointer itself |
|||
char* msg2 = strdup1(msg.c_str()); |
|||
// C strings can be directly output to std::cout, so we don't need |
|||
// to put it back into a string to output it. |
|||
std::cout << msg2; |
|||
// call the FORTRAN function (through the wrapper): |
|||
std::cout << multiply(3, 5) << std::endl; |
|||
// since strdup1 allocates with malloc, it must be deallocated with |
|||
// free, not delete, nor delete[], nor operator delete |
|||
std::free(msg2); |
|||
} |
|||
</lang> |
</lang> |
||