C++ "mangles" the linker names of its functions to include the data types of the function arguments. This is good, because it lets you overload function names; but it's bad, because plain C and assembly don't do anything special to the linker names of functions.
In C or assembly, a function "foo" shows up as just plain "foo" in the linker. In C++, a function foo shows up as "foo()" or "foo(int,double,void *)". (Check out the disassembly to be sure how your linker names are coming out.)
So if you call C or assembly code from C++, you have to turn off C++'s name mangling by declaring the C or assembly routines 'extern "C"', like this:
extern "C" void some_assembly_routine(int param1,char *param2);or wrapped in curly braces like this:
extern "C" {
void one_assembly_routine(int x);
void another_assembly_routine(char c);
}
In fact, it's common to provide a "magic" header file for C code that automatically provides 'extern "C"' prototypes for C++, but just works normally in plain C:
#ifdef __cplusplus /* only defined in C++ code */Definitely try these things out yourself:
extern "C" {
#endif
void one_assembly_routine(int x);
void another_assembly_routine(char c);
#ifdef __cplusplus /* only defined in C++ code */
}
#endif
int bar(int i,int j) {(executable NetRun link)
printf("bar(%d,%d)\n",i,j);
return i;
}
extern "C" int bar(int i,int j);(executable NetRun link)
int foo(void)
{
return bar(2,3);
}
Code written in |
With name |
Has linker name |
C++ |
int bar(int a,int b) |
bar(int,int) <- But "mangled" to be alphanumeric... |
C++ |
extern "C" int bar(int a,int b) | bar |
C |
int bar(int a,int b) |
bar |
Assembly |
global bar bar: |
bar |
Fortran |
SUBROUTINE bar() |
bar_, BAR, BAR_, bar__, or some such. Disassemble to be sure... |
When passing... |
In C/C++, you... |
In Fortran, you... |
an int |
push the int |
push a pointer to the integer |
an array |
push a pointer to the first element of the array |
push a pointer to the first element of the array |
a char |
push an int containing the character's value |
push a pointer to the character |
function foo()Here's a "do loop" (the Fortran equivalent of C/C++ "for"):
INTEGER foo
i = 7;
foo = i + 3;
end function
function foo()
INTEGER foo
do i=1,10
CALL print_int(i)
end do
foo = i + 3;
end function
Note that "print_int" is defined in NetRun's "inc.c" as:
CDECL void print_int__(int *i) {print_int(*i);}
Here,