Follow up question about linking to MKS using stdcall

Follow up question about linking to MKS using stdcall

Hi,

This is a follow up question to my last post.

Previously, I had a problem linking the function
dgetrf in C++ using Visual Studio 6 with the stdcall calling
convention. The solution to this problem as Tim pointed
out was to call the function with capital letters, DGETRF.
Then it links and runs with no problem.

However, now that I have the matrix in LU form, I want to
solve it. So I tried calling the function DGETRS. When I
do this I get the same linking error, now with DGETRS:

HFTestRoutines.obj : error LNK2001: unresolved external symbol _DGETRS@36
../lib/mytests.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

The call looks like this:

char tran = 'C';
int dm = 10;
int nrhs = 1;
int nchar = 1;
int info = l;

DGETRS(&tran, &dm, &nrhs, a, &dm, ipiv, rhs, &dm, &info);

where

a is the same matrix (*double) that goes into DGETRF;
ipiv is a *int of length 10 output by DGETRF;
rhs is a *double of length 10.

I have the vague sense that the problem might have something
to do with the different way that C and Fortran treat characters,
but I can't see why (even if this is the problem) the function
won't link.

(I tried all lowercase, and this does not work either).

Once again, any help would be greatly appreciated. I thought
this afternoon that these problems were behind me and now I feel
like I'm back at square one!

10 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

You are correct and I am not certain I can help you at the moment. As I stated in an earlier note there is a difference between CVF interface and stdcall but I have not been able to put my hands on the documentation that differentiates the details.

Bruce

The mkl_s.lib conforms with a modified version of stdcall which permits character strings to be called from Fortran. I suppose it shouldn't be too difficult to use the stdcall interface with older Windows C compilers, when calling functions which don't have a character string argument. Needless to say, there are limitations on this business of using ABIs which were obsoleted several years ago.

Hi Bruce,
I think I've figured out what is going on. The
declaration of the function DGETRS in
mkl_lapack64.h is not quite right.

The declaration is

void DGETRS(char *trans,int *n,int *nrhs,double *a,int *lda,int *ipiv,double *b,int *ldb,int *info);

But looking around on the web, it seems that when a FORTRAN
function takes a character argument, the corresponding C call
must use two arguments: a *char, and then an int that says
how long the character string is. See for example

http://www.nag.co.uk/numeric/FLOLCH/chw3220da.html

So the declaration should be

void DGETRS(char *trans, int nchar, int *n,int *nrhs,double *a,int *lda,int *ipiv,double *b,int *ldb,int *info);

When I use this declaration, the program compiles and links.
I'm guessing all the declarations in mkl_lapack64.h and
mkl_lapack32.h that have character arguments might require this
change.

(I have not yet run the function to test the output, so
there could be more surprises lurking here).

Jeff

Hi Tim,
Thanks for the response. I just posted at note at the
same time as you again. Do you think that what
I propose in that note might work?
Jeff

Jeff,

If you look at the name of the function in mkl_s.lib with something like dumpbin or nm you will see that the name is DGETRF@40. The "40" indicates the number of bytes needed to pass all the arguments with a 4 byte integer (address) needed for each paramater. However, if you count the number of parameters there are only 9 parameters so why "40" and not "36"? The answer is that a hidden integer is needed for each string indicating the length of the string. What I could not recall was which interface (stdcall or CVF) put those string lengths adjacent to the strings and which put them at the end of the list of parameters.

Bruce

Bruce, thanks for the response. If I understand it then,
the int corresponding to the string length either comes
after the character argument, or as the last argument -
but you don't recall which. I'll try both ways and see what happens.

Do you agree with my earlier point that one must
change the declaration in the .h file before compiling?

Also, here is an unrelated question that you or Tim might
be able to address.
I need to build my DLL as stdcall.
Does that mean that I must use the mk_s.lib to link.
That is, would something terrible happen if
I built my DLL using stdcall and tried to link to
the mk_c.lib?

Jeff

mkl_s.lib should be set up with the string length argument immediately after the character string argument, as that was the default for the CVF compiler. If you supply a prototype for the C interface, you must make it agree with this scheme.

Tim has already answered the question about where the string length belongs for the CVF interface.

We have made things easy for you to use dll. In the lib directory is a file mkl_s_dll.lib. If you link that into your program you will need the dlls in you path as all you will have linked in is the software to import the dlls. (We have equivalent functionality for cdecl - mkl_c_dll.lib).

Bruce

Tim, Bruce,
Thanks for your help on these points. I appreciate it.
Regards, Jeff

Leave a Comment

Please sign in to add a comment. Not a member? Join today