Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

linking with c/c++

Giang_Bui
Beginner
1,568 Views

Hello

I have problem linking f90 code with c/c++ code using ifort. The situation is like this:

The fortran code callmesh_tetgen_f.f90 call the function callmesh_tetgen_c defined in header callmesh_tetgen_c.h:

SUBROUTINE callmesh_tetgen_c(iflag,itask,ndim,npt,nnode,nelem,nnodb,neleb,nholes,cord,lnods,lnodb,cdholes,iostat)
!DEC$ ATTRIBUTES C :: callmesh_tetgen_c

....................
END SUBROUTINE callmesh_tetgen_c

The callmesh_tetgen_c.cpp implement the function callmesh_tetgen_c:

extern "C" void callmesh_tetgen_c(...)
{

...

tetrahedralize(...);

...

}

This function call "tetrahedralize" defined in tetgen library (in c++). When I link my program to callmesh_tetgen_c.cpp using

ifort -cxxlib -o mainpg mainpg.o callmesh_tetgen_c.cpp.o libtetgen.a

throw compilation error:

callmesh_tetgen_c.cpp:(.text+0x311): undefined reference to `tetrahedralize(char*, tetgenio*, tetgenio*, tetgenio*, tetgenio*)'

It seems that using ifort doesn't link c++ object to c++ static library correctly. How could I resolve this problem?

Giang Bui

0 Kudos
8 Replies
mecej4
Honored Contributor III
1,568 Views

I cannot quite tell from your code snippet, but if tetrahedralize is called with C linkage in callmesh_tetgen_c.cpp but is defined with C++ linkage in your library, the decorated names would not match.

0 Kudos
Giang_Bui
Beginner
1,568 Views

So what should be the correct "decorated" name? nm libtetgen.a gives me:

0000000000001140 T _Z14tetrahedralizeP14tetgenbehaviorP8tetgenioS2_S2_S2_
0000000000000018 r _Z14tetrahedralizeP14tetgenbehaviorP8tetgenioS2_S2_S2_$$LSDA

0 Kudos
mecej4
Honored Contributor III
1,568 Views

There is no simple way (and in effect, no possible way) of calling routines with C++ linkage from Fortran.

If you have the source code of your library, you can surround the source lines of function tetrahedralize by extern "C" {} and recompile, after making sure that there are no invocations of the same function with C++ linkage.

0 Kudos
Giang_Bui
Beginner
1,568 Views

Hi mecej4

I tried that way and it doesn't work. Is this related to name mangling or so ?

0 Kudos
mecej4
Honored Contributor III
1,568 Views

Hoang Giang B. wrote:

I tried that way and it doesn't work. 

Please clarify: did you modify the source code of the library function as I stated above, and rebuild the library? 

0 Kudos
Giang_Bui
Beginner
1,568 Views

That's correct. In the library sources I added

extern "C" void tetrahedralize(char *switches, tetgenio *in, tetgenio *out,
                    tetgenio *addin = NULL, tetgenio *bgmin = NULL);

And recompile the library. However it still showed the error:

callmesh_tetgen_c.cpp:(.text+0x311): undefined reference to `tetrahedralize'

0 Kudos
mecej4
Honored Contributor III
1,568 Views

What do get when you run nm on the new version of the library, as you did above with the old version?

0 Kudos
Giang_Bui
Beginner
1,568 Views

That's fine. I have checked the library and found that the correct "tetrahedralize" is undef'ed in source file. Now everything compiles fine (with the extern "C")  :)

Thank you very much.

0 Kudos
Reply