pvf link error making dll using calls to C routines

Hi,

I am trying to convert some old Fortran currently working under the Intel compiler. This is being compiled as a dll, as it is called from a C program, and in addition it calls some C functions located in another library. It had the old-style Intel interface declarations for calling the C routines. I have changed those to your format, which includes the NAME=‘c_function’ to translate to the C routine name. When the link operation is called to generate the library, all the ‘c_function’ names show as unresolved external symbols.

Do I have to somewhere specify the C library containing these c_functions to the pvf project? Is there something else I am missing?

Do I have to have the “USE ISO_C_BINDING” module specified? What I saw in the module declaration did not appear to require its use, and if I have to add it in, that is modifying around 100 routines, which I would rather avoid unless absolutely necessary.

Other thoughts?

Thanks.

-alan

Hi Alan,

I can think of a couple of reasons why this would happen. First it could be pilot error on how you’re using ISO_C_BINDING, or it could be the C calling convention being used.

Can you please post an example of the ISO_C_BINDING interface that you created and well as the corresponding unresolved external symbol message?

Do I have to have the “USE ISO_C_BINDING” module specified?

Yes, but it should produce an syntax error not a link error. The exception being if you’re only using the “bind” keyword which we’ll accept without the use statement.

What I saw in the module declaration did not appear to require its use, and if I have to add it in, that is modifying around 100 routines,

The easiest thing to do is create a module to hold the interface block. Granted, you’d still need to add a use statement in each routine, but you only need to write the interface once.

Are you using 32-bit or 64-bit Windows? Win32 has multiple calling conversion which need to match between C and Fortran. For details, please see Chapter 13 of the PGI User’s Guide.

Also, which C compiler are you using and with what options?

  • Mat

Mat,

First, a clarification. I am not currently using ISO_C_BINDING as it was not clear to me that it was required.

The old interface style (Intel Fortran) was:
SUBROUTINE ZZAMFREE [C, ALIAS: ‘_zzamfree’] (IP, IBLOCK)
INTEGER IP[REFERENCE]
INTEGER IBLOCK[REFERENCE]
END SUBROUTINE ZZAMFREE

which I replaced with:
SUBROUTINE ZZAMFREE(IP, IBLOCK) BIND(C, NAME=‘_zzamfree’)
INTEGER IP
INTEGER IBLOCK
END SUBROUTINE ZZAMFREE

Which generates to following error message(s):
Error 144 unresolved external symbol __zzamfree maklitbr.obj

Note: in posting this, I notice that there are two underscores at the beginning of the name instead of the single one in the interface declaration (this was hard to see in the VS formatting of the message). However, dropping the underscore so that only a single one appears in the error message does not change the error message.

I am running 64-bit Windows7 with PVF12.4 and VS2010. I have tried both 32-bit and 64-bit compiles (the old code is 32-bit, so I expect some issues when actually trying to get everything to 64-bit).

The interface block, which contains about a dozen interfaces, is already in an include file. However, if I convert it to a module, or use a module in the include file, I will have to reorder the include lines in a boatload of routines.

The last compile was done by others under VS2008. The C compiler used is Microsoft Visual C++ as included in respective Visual Studio version. Unless I am missing something, all the C options appear to be default. The solution has a total of 58 projects, of which this is only one; but it does most of the heavy lifting. (I thought that when building a library, any external naming issues would only show up when actually invoking the library during execution, so I am a bit puzzled by this.)

-alan

Mat,

OK, I am not sure quite what was going on. However…

This morning I just deleted the entire Fortran project and recreated it from scratch. And it generated the library. I am not sure what I did differently, but obviously I did something.

I still have to verify proper operation in the final executable (name conventions, etc), but at least now I have some place to start.

Thanks for your help and I will let you know if there a any more issues.

-alan

Thank for letting me know. My guess is that there was an old reference someplace that didn’t get updated.

Win32 calling conventions are not fun given the multiple non-compatible options. Win64 is much better since you only have to deal with the basic inter-language calling issue rather than the OS calling conventions.

  • Mat