- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have a problem with the linking of a static library.
The compiler error is that it doesn't find the symbols. I normally work in linux, but now I need to compile my code in windows.
I'm not really sure how I can see the symbol table in the library. I tested the library with compaq visual fortran and it's working perfectly. The same occurs in linux with the intel compiler 9.0
Can someone help me with this ??
thanks a lot!!
clabra
I have a problem with the linking of a static library.
The compiler error is that it doesn't find the symbols. I normally work in linux, but now I need to compile my code in windows.
I'm not really sure how I can see the symbol table in the library. I tested the library with compaq visual fortran and it's working perfectly. The same occurs in linux with the intel compiler 9.0
Can someone help me with this ??
thanks a lot!!
clabra
Link Copied
14 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dumpbin -symbols foo.lib
Do this from a "build environment for Fortran IA-32 applications" window.
Do this from a "build environment for Fortran IA-32 applications" window.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you Steve.
The problem was the calling convention for the external subroutine. Now I resolved almost everything, but one of the subroutines is called with the name "BEGINRESULTHEADER@32" and in the library the symbol is "BEGINRESULTHEADER@36" ....
Exist solution for this kind of problem ??? maybe using !DEC ??
thanks
The problem was the calling convention for the external subroutine. Now I resolved almost everything, but one of the subroutines is called with the name "BEGINRESULTHEADER@32" and in the library the symbol is "BEGINRESULTHEADER@36" ....
Exist solution for this kind of problem ??? maybe using !DEC ??
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have a mismatch in expectations for the number and/or datatypes of the arguments. My guess is that the call is passing a non-character where the routine is expecting a character argument. These need to match.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I made changes with the character argument in the subroutine, but the new symbol was "BEGINRESULTHEADER@40". Maybe the problem is with the implementation of the libray. It was written in C, with a cfortran.h interface to fortran.
(http://www.gidhome.com/support/gidpost.subst)
I don't sure about the work of the cfortran.h with the intel compiler. In unix it worked perfectly.
(http://www.gidhome.com/support/gidpost.subst)
I don't sure about the work of the cfortran.h with the intel compiler. In unix it worked perfectly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I see:
There are 6 arguments, 3 of which are characters; that gives (6*4) + (3*4) = @36 bytes. I assume there's a Fortran wrapper routine in the library, which takes care about proper calling of C version (_GiD_BeginResultHeader, which supposedly has total of 28 bytes (6*4) + extra 4 for double-by-value).
Thus, it seems it's still your error?
Jugoslav
int GiD_BeginResultHeader(
char * Result,
char * Analysis,
double step,
GiD_ResultType Type,
GiD_ResultLocation Where,
char * GaussPointsName);
There are 6 arguments, 3 of which are characters; that gives (6*4) + (3*4) = @36 bytes. I assume there's a Fortran wrapper routine in the library, which takes care about proper calling of C version (_GiD_BeginResultHeader, which supposedly has total of 28 bytes (6*4) + extra 4 for double-by-value).
Thus, it seems it's still your error?
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks Jugoslav.
Now I see it was my error ....
I used an example that not work, and I used "NULL" in "GiD_ResultLocation Where" argument.
( character(4) :: NULL = char(0)//char(0)//char(0)//char(0) )
by the way, someone know if it's possible to use this interface without setting the call convention with "CVF"?
In my routine I can't use other modules.
Now I see it was my error ....
I used an example that not work, and I used "NULL" in "GiD_ResultLocation Where" argument.
( character(4) :: NULL = char(0)//char(0)//char(0)//char(0) )
by the way, someone know if it's possible to use this interface without setting the call convention with "CVF"?
In my routine I can't use other modules.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, yes, but not without a hassle.
I took a brief look at the GiD package but I didn't find INTERFACE statements, which would take care about these details. Thus, I assume that GID_WHATEVER functions are Fortran wrappers burried inside the library and built with CVF.
So, if you'd like to call these with the correct calling convention (CVF) but having the rest of the code with another calling convention (default), you have to spell out the interfaces yourself (or, alternatively, write yet another wrapper file). If I recall correctly, there isn't such thing as !DEC$ATTRIBUTES CVF, (which would ease you the job), so you'll need something like:
!DEC$ATTRIBUTES STDCALL, DECORATE, REFERENCE, MIXED_STR_LEN_ARG, ALIAS "GID_WHATEVER": GID_WHATEVER.
(Maybe just the above declaration is enough but I'm not sure about it, or maybe the full interface body is required; try it yourself).
Jugoslav
I took a brief look at the GiD package but I didn't find INTERFACE statements, which would take care about these details. Thus, I assume that GID_WHATEVER functions are Fortran wrappers burried inside the library and built with CVF.
So, if you'd like to call these with the correct calling convention (CVF) but having the rest of the code with another calling convention (default), you have to spell out the interfaces yourself (or, alternatively, write yet another wrapper file). If I recall correctly, there isn't such thing as !DEC$ATTRIBUTES CVF, (which would ease you the job), so you'll need something like:
!DEC$ATTRIBUTES STDCALL, DECORATE, REFERENCE, MIXED_STR_LEN_ARG, ALIAS "GID_WHATEVER": GID_WHATEVER.
(Maybe just the above declaration is enough but I'm not sure about it, or maybe the full interface body is required; try it yourself).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looking at the source of the library you can see that it was written completely in C, and the interface is the cfortran library ( I don't really know how this interface works!! ). I understand that the library does not recognize the intel compiler (maybe I'm wrong) .... but in unix (with intel) I use it without problem. The problem occurs only in Windows.
The use of the "intel" directives is an easy option, but my idea is to make a standard code. In unix I use intel and G95. Maybe to write my own wrapper is a good option. I made this with other libraries.
clabra
The use of the "intel" directives is an easy option, but my idea is to make a standard code. In unix I use intel and G95. Maybe to write my own wrapper is a good option. I made this with other libraries.
clabra
Message Edited by clabra on 12-14-2005 09:20 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I took a brief look onto it. DUMPBIN reveals that GID_FOO@n (fortran-callable) version of exported functions originate from file gidpostfor.c. There, they're defined using CFortran.h macros FCALLSCFUN*.
Since CFortran.h is pretty difficult to untangle, your best bet would be to:
- Find a newer version of CFortran.h supporting IVF on Windows (the version shipped with GiD library is pretty old, since 2001.)
- Replace the CFortran.h in the GiD package with that version
- Rebuild the GiD library.
This CFortran version looks like a good candidate... checking... no it seems it isn't. Uh.
Try searching or posting on comp.lang.fortran I googled some hints that it's possible, but nothing definitive.
Jugoslav
Since CFortran.h is pretty difficult to untangle, your best bet would be to:
- Find a newer version of CFortran.h supporting IVF on Windows (the version shipped with GiD library is pretty old, since 2001.)
- Replace the CFortran.h in the GiD package with that version
- Rebuild the GiD library.
This CFortran version looks like a good candidate... checking... no it seems it isn't. Uh.
Try searching or posting on comp.lang.fortran I googled some hints that it's possible, but nothing definitive.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jugoslav ....
I found cfortran.h version 4.4-8, but the support for the intel compiler is via a patch ?? I didn't use it, but I will make some tests.
For now, I wrote my own wrapper for the library, without cfortran, and it worked perfectly. 2 files, one in C (replace the cfortran interface gidpostfor.c ) and the other is a fortran module who call the library.
fortran_wrapper_gidpost.c :
...
#include "gidpost.h"
...
void C_OPENPOSTMESHFILE( char* name, int* mode )
{
GiD_OpenPostMeshFile( name, mode[0] )
}
...
...
!-------module_gidpost.f90 -------!
module gidpost
....
....
suboutine GiD_OpenPostMeshFile( fname, mode )
character(*), intent(in) :: fname
integer, intent(in) :: mode
call C_OPENPOSTMESHFILE( name, mode )
end subroutine GiD_OpenPostMeshFile
....
end module gidpost
I found cfortran.h version 4.4-8, but the support for the intel compiler is via a patch ?? I didn't use it, but I will make some tests.
For now, I wrote my own wrapper for the library, without cfortran, and it worked perfectly. 2 files, one in C (replace the cfortran interface gidpostfor.c ) and the other is a fortran module who call the library.
fortran_wrapper_gidpost.c :
...
#include "gidpost.h"
...
void C_OPENPOSTMESHFILE( char* name, int* mode )
{
GiD_OpenPostMeshFile( name, mode[0] )
}
...
...
!-------module_gidpost.f90 -------!
module gidpost
....
....
suboutine GiD_OpenPostMeshFile( fname, mode )
character(*), intent(in) :: fname
integer, intent(in) :: mode
call C_OPENPOSTMESHFILE( name, mode )
end subroutine GiD_OpenPostMeshFile
....
end module gidpost
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm affraid that it works perfectly by chance -- character arguments are a pain.
Fortran passes the length of char string around; C expects char(0)-termination. Due to ifort's __cdecl calling convention, you won't screw the stack if you omit the length argument (as you did), which is passed at the end of argument-list, but you didn't take care about char(0)-termination. So, if a binary zero happens to be in memory after the actual argument name, it will "work", but if it doesn't, the outcome can be pretty much anything.
Best, you should declare an int namelen argument at the end of char-list, malloc() a char array of namelen+1 elements, strcpy the name argument to it and assign a at positon namelen. THEN you can pass it to the "real" C routine. (If there are some output character arguments, reverse the procedure). I'm pretty sure that's what CFortran.h wrappers do.
Jugoslav
Fortran passes the length of char string around; C expects char(0)-termination. Due to ifort's __cdecl calling convention, you won't screw the stack if you omit the length argument (as you did), which is passed at the end of argument-list, but you didn't take care about char(0)-termination. So, if a binary zero happens to be in memory after the actual argument name, it will "work", but if it doesn't, the outcome can be pretty much anything.
Best, you should declare an int namelen argument at the end of char-list, malloc() a char array of namelen+1 elements, strcpy the name argument to it and assign a at positon namelen. THEN you can pass it to the "real" C routine. (If there are some output character arguments, reverse the procedure). I'm pretty sure that's what CFortran.h wrappers do.
Jugoslav
Message Edited by JugoslavDujic on 12-16-2005 12:57 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe you about the cfortran.h, but I think maybe it's good an option more "simple" for the wrapper.
You are right about the problem with the strings. my first idea was to use an array of character(1) ( like iso_varying_string module), but I had some of garbage in the end of the array. After your comment I use this modification:
!------
suboutine GiD_OpenPostMeshFile( fname, mode )
character(*), intent(in) :: fname
integer, intent(in) :: mode
integer :: i, n
character(1) :: c_fname(len(fname))
n = len(fname)
forall (i=1:n) c_fname(i)=fname(i:i)
c_fname(n+1) = char(0)
call C_OPENPOSTMESHFILE( c_fname, mode )
end subroutine GiD_OpenPostMeshFile
!------
It's working. What do you think about this possibility ?
clabra
You are right about the problem with the strings. my first idea was to use an array of character(1) ( like iso_varying_string module), but I had some of garbage in the end of the array. After your comment I use this modification:
!------
suboutine GiD_OpenPostMeshFile( fname, mode )
character(*), intent(in) :: fname
integer, intent(in) :: mode
integer :: i, n
character(1) :: c_fname(len(fname))
n = len(fname)
forall (i=1:n) c_fname(i)=fname(i:i)
c_fname(n+1) = char(0)
call C_OPENPOSTMESHFILE( c_fname, mode )
end subroutine GiD_OpenPostMeshFile
!------
It's working. What do you think about this possibility ?
clabra
Message Edited by clabra on 12-16-2005 04:36 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But you're overwriting the last character of name now. Where is C_OPENPOSTMESHFILE defined? Is it a C or Fortran routine from GiD, or one of yours?
I'd still stick to C wrappers, as they're more flexible (if you want to keep portability of Fortran part). Still more, I'd still prefer to have a working version of CFortran.h. (By the way: have you tried building CFortran.h by #define-ing symbol corresponding with some of older compilers' listed? Ifort (unlike CVF) shares most of argument-passing mechanism with other compilers.
So, a wrapper for IVF written in C for GiD_OpenPostMeshFile(char*, int) would look like:
Jugoslav
I'd still stick to C wrappers, as they're more flexible (if you want to keep portability of Fortran part). Still more, I'd still prefer to have a working version of CFortran.h. (By the way: have you tried building CFortran.h by #define-ing symbol corresponding with some of older compilers' listed? Ifort (unlike CVF) shares most of argument-passing mechanism with other compilers.
So, a wrapper for IVF written in C for GiD_OpenPostMeshFile(char*, int) would look like:
extern "C" void F_OPENPOSTMESHFILE(char* name, int* mode, int namelen)
{
//prolog - needed only if name is INTENT(IN)
char* cname = new char[namelen+1];
memcpy(cname, name, namelen);
cname[namelen] = '';
GiD_OpenPostMeshFile(cname, *mode);
//epilog (blank-padding) - needed only if name is INTENT(OUT):
strncpy(cname, name, strlen(cname))
for (int i=strlen(cname); iname = ' ';
delete[] cname;
}
Jugoslav
Message Edited by JugoslavDujic on 12-16-2005 02:33 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C_OPENPOSRMESHFILE is a EXTERN routine of my wrapper file in C.
If I make :
forall(i=1:len(fname)) c_fname(i)=fname(i:i)
c_fname(len(fname)+1) = char(0)
is "c_fname" equivalent to your "cname" string ???
My idea it was to pass directly the string like an C character array. I'm not sure if is correct, but it's work in my case.
Your implementation of the wrapper is very interesting, but don't have problem with the "name" argument in C???
clabra
If I make :
forall(i=1:len(fname)) c_fname(i)=fname(i:i)
c_fname(len(fname)+1) = char(0)
is "c_fname" equivalent to your "cname" string ???
My idea it was to pass directly the string like an C character array. I'm not sure if is correct, but it's work in my case.
Your implementation of the wrapper is very interesting, but don't have problem with the "name" argument in C???
clabra

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