- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to reference variables from a module in a c language routine. I'm using the format specified here:
Is there something else I need to do during linking to make this happen? I get an error from my compile and link commands:
Starting compile and link
ifort /Qopenmp-report2 /Qopenmp /integer_size:64 /real_size:64 /fpe:0 /names:lowercase /iface:cref /module:..\..\..\x64\Current /MT /libs:dll /iface:mixed_
str_len_arg /include:..\..\..\include /include:..\..\..\include\fluint /include:..\..\..\proces /assume:byterecl /extend_source:132 /O3 /list /traceback /I
NCREMENTAL:NO
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.3.202 Build 20140422
Copyright (C) 1985-2014 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:astap.exe
-subsystem:console
-incremental:no
-defaultlib:libiomp5md.lib
-nodefaultlib:vcomp.lib
-nodefaultlib:vcompd.lib
/LIBPATH:..\..\..\DLLs_x64
SaveSetWriter.lib
..\..\..\x64\procesCur.lib
..\..\..\x64\utilityCur.lib
multicalc.lib
tdsubproc.lib
statwin.lib
sfmatlab.lib
savesetwriter.lib
/STACK:1000000000
/MAP
/MANIFEST
/NODEFAULTLIB:msvcrt.lib
/NODEFAULTLIB:dfordll.lib
/NODEFAULTLIB:msvcrtd.lib
/NODEFAULTLIB:dfor.lib
/DEBUG
/LIBPATH:..\..\..\DLLs_x64
SaveSetWriter.lib
..\..\..\x64\procesCur.lib
..\..\..\x64\utilityCur.lib
multicalc.lib
tdsubproc.lib
statwin.lib
sfmatlab.lib
savesetwriter.lib
/STACK:1000000000
/MAP
/MANIFEST
/NODEFAULTLIB:msvcrt.lib
/NODEFAULTLIB:dfordll.lib
/NODEFAULTLIB:msvcrtd.lib
/NODEFAULTLIB:dfor.lib
/DEBUG
astap.obj
procesCur.lib(supportp.obj) : error LNK2001: unresolved external symbol LUMP_MOD_mp_LTYPE
astap.exe : fatal error LNK1120: 1 unresolved externals
LUMP_MOD is the module and LTYPE is the variable name
My C declaration is:
extern __int64 LUMP_MOD_mp_LTYPE[];
My fortran declaration is (note the compile arguments make all variables 64 bits)
MODULE LUMP_MOD
INTEGER,ALLOCATABLE :: LTYPE(:)
Thanks!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ditch the /names:lowercase and /iface:cref. Use the C interoperability features of the language to control names and argument passing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
non-trivial to implement I think (we support multiple fortran compilers). Is there a way to find what the symbol name is as it stands? I open .lib and .obj files in an editor to find routine names easily enough. I wasn't able to do that with the .mod files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Especially if you need to support multiple compilers, you will want to use a portable way to access the Fortran global from C. Name mangling of module entities is done differently by different compilers.
Unfortunately, while the C interop features support mapping of global array variables if the size is fixed at compile time, this is not the case for ALLOCATABLE entities. However, you can construct an accessor function that provides the address. The following should work:
Fortran module:
module mod_glob use, intrinsic :: iso_c_binding implicit none integer(c_int), allocatable, target :: a(:) ! target attribute needed for c_loc invocation integer(c_size_t), parameter :: size = 7 contains subroutine return_moddat(dat, sz) BIND(C) type(c_ptr) :: dat integer(c_size_t) :: sz integer :: i dat = c_null_ptr sz = 0 if (allocated(a)) then dat = c_loc(a) sz = size(a) end if end subroutine return_moddat end module mod_glob
C program that accesses the module variable:
void return_moddat(int **dat, size_t *sz); int main() { int *dat; size_t sz, i; // call some other function that allocates the module variable return_moddat(&dat, &sz); for (i=0; i<sz; i++) { printf("i, a: %i %i\n",i,dat); } }
Cheers
Reinhold
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dajum wrote:
non-trivial to implement I think (we support multiple fortran compilers). Is there a way to find what the symbol name is as it stands? I open .lib and .obj files in an editor to find routine names easily enough. I wasn't able to do that with the .mod files.
I'm not sure I get your point. The point of the C interoperability features is to enable mixed-language programming in a more portable manner an it is part of standard fortran. This surely makes supporting multiple compilers/platforms easier?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your problem is not with the.mod files - those are read by the Fortran compiler only. Doing "dumpbin -symbols" on the .lib will give you the global symbol names. You really should use the F2003 standard syntax for specifying C names for module variables and procedures - it is portable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dajum wrote:
non-trivial to implement I think
True, but this is a one-time effort (to port from a fixed name decoration system to the C-interop version). You have to assess whether the effort is justifiable.
(we support multiple fortran compilers). Is there a way to find what the symbol name is as it stands? I open .lib and .obj files in an editor to find routine names easily enough. I wasn't able to do that with the .mod files.
The module files from one compiler are probably unintelligible to any other compiler. If you have to support a number of Fortran compilers, you can either distribute compiler-specific module files, or provide the source code to generate the .mod files (this works esp. for interfaces). However, there is little need to try to parse the .mod files.
The advantage from using C-interoperability is that MS C is, de-facto, the standard for the Windows OSes, as is GCC for Linux. The Intel Fortran compiler on each platform knows about the "companion C processor" and emits symbols compatible with that C processor.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the help. Got it working now.
I want to switch to using the more standard name specifiers, but with 5000+ routines, 200+ interfacing functions, and thousands of users working with what works now, changes happen slowly.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page