By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,143 Members | 1,919 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,143 IT Pros & Developers. It's quick & easy.

Need Help Calling A Fortran 77 (.for) DLL

P: 4
Hey Everyone,

I am doing a VB6 to C# conversion and everything was going smoothly until I realized that I needed to call a Fortran 77 (.for) .dll inside my code. I have looked through everything I have found using Google and have still been unable to get it to successfully work. Currently the following call works about 75% of the time, but the other 25% of the time my program just calls the .dll and then it simply exits; no error/exception occurs, it just quits without executing anymore code. As you can see I have tried multiple ways to catch/generate error messages. I have no Fortran experience and I was told to leave the Fortran code alone, since it has been around and working since the 70ís.

From what I can tell the Fortran code only has one subroutine. I have included the header/parameters below:

SUBROUTINE FORTRANCALLA(INPUTL, TABLEL, NAMEL2, COMMAL, LOADL)
EXTERNAL F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F20

!DEC$ ATTRIBUTES DLLEXPORT :: FORTRANCALLA
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'FORTRANCALLA' :: FORTRANCALLA
!DEC$ ATTRIBUTES REFERENCE :: INPUTL
!DEC$ ATTRIBUTES REFERENCE :: TABLEL
!DEC$ ATTRIBUTES REFERENCE :: NAMEL2
!DEC$ ATTRIBUTES REFERENCE :: COMMAL
!DEC$ ATTRIBUTES REFERENCE :: LOADL

CHARACTER(80), INTENT(IN) :: INPUTL
CHARACTER(80), INTENT(IN) :: TABLEL
CHARACTER(80), INTENT(IN) :: NAMEL2
CHARACTER(4), INTENT(IN) :: COMMAL
CHARACTER(80), INTENT(IN) :: LOADL


It appears C++ was used to wrap the .for file and generate a .dll which was called in the VB6 program using the following code:

Call Fortran.FORTRANCALLA(infilecalc, tablecalc, destination2, format, loadcond)

Public Declare Sub FORTRANCALLA Lib "Name.dll" _
(ByVal INPUTL As String, ByVal TABLEL As String, ByVal NAMEL2 As String, ByVal COMMAL As String, ByVal LOADL As String)

It appears that the VB6 program also has problems with the call, but not as frequently. However, it also handles the failed .dll call much better and does not crash. If possible I would just like my program not to fatally crash.

Here is the code I am currently working with and I am calling the exact same .dll that is currently being used in the VB6 version:

Expand|Select|Wrap|Line Numbers
  1. static class Fortran
  2.       {
  3.             [DllImport("Name.dll")]
  4.             private static extern bool FORTRANCALLA(
  5.                   StringBuilder infilecalc,
  6.                   StringBuilder tablecalc,
  7.                   StringBuilder destination2,
  8.                   StringBuilder format,
  9.                   StringBuilder loadcond);
  10.  
  11.             public static void Calculate(string infilecalc, string tablecalc, string destination2, string format, string loadcond)
  12.             {
  13.                   string tempOutputPath = FileMod.GetTemporaryDirectory() + "NameTemp.tmp";
  14.  
  15.                   StringBuilder bldrInFileCalc = new StringBuilder(infilecalc, 80);
  16.                   StringBuilder bldrTableCalc = new StringBuilder(tablecalc, 80);
  17.                   StringBuilder bldrDestination2 = new StringBuilder(tempOutputPath, 80);
  18.                   StringBuilder bldrFormat = new StringBuilder(format, 4);
  19.                   StringBuilder bldrLoadCond = new StringBuilder(loadcond, 80);
  20.  
  21.                   try
  22.                   {
  23.                         if (!FORTRANCALLA(bldrInFileCalc, bldrTableCalc, bldrDestination2, bldrFormat, bldrLoadCond))
  24.                               MessageBox.Show(new System.ComponentModel.Win32Exception().ToString());
  25.                   }
  26.                   catch (Exception e)
  27.                   {
  28.                         MessageBox.Show(e.Message);
  29.                   }
  30.  
  31.                   //FORTRANCALLA(bldrInFileCalc, bldrTableCalc, bldrDestination2, bldrFormat, bldrLoadCond);
  32.  
  33.                   File.Copy(tempOutputPath, destination2, true);
  34.                   File.Delete(tempOutputPath);
  35.             }
  36.       }
Right now I cannot find a pattern to the crashes. I could work with the same files, making identical calls to the .dll, and sometimes it works sometimes it doesn't. At first I thought it was something to do with memory allocation, but I don't think that is the case because sometimes it crashes on the first call. Sometimes it only crashes once, sometimes it crashes multiple uses in a row, and sometimes you can make many calls before it starts crashing again.

Does anyone have any ideas? Because I am officially out of ideas...

Thanks,
Nitsua
Aug 12 '08 #1
Share this Question
Share on Google+
4 Replies


Plater
Expert 5K+
P: 7,872
Are any of the parameters you pass to the fortran dll "return" or "out" parameters (or even passed by ref)?
If a StringBuilder is going to be modified by the function in an unmanaged DLL, you need to supply a default size for it, a size big enough to handle whatever text would be coming back. I see you appear to be giving sizes but I wonder if they are big enough?

EDIT: ok so you pass everything by value...and all that work just to get a true/false? Seems like a big waste, unless your strings become floating point numbers, fortran's not real usefull for anything other then floating point calculations
Aug 12 '08 #2

P: 4
The strings I pass in are actually file paths and one format paramater (txt, doc, ect) and the strings are never altered. The fortran is actually taking values from a couple of input files and doing calculations and then writing them to an output file in the request format. The function never actually passes out a bool, but if you make the call a bool then it lets you determine (sometimes) if the call failed or not.
Aug 12 '08 #3

Plater
Expert 5K+
P: 7,872
Hmm yes on closer look you are making everything to sizes matching that of the fortran header.
Is there any common pattern between filenames(and directories) or file types that could be the cause of the failure?
Such as fortran cannot handle a character in a special path or anything like that?
Aug 12 '08 #4

P: 4
I think I may have figured it out. One of the paths was a server path (\\server\share\...) and when I moved the file locally it seems to be working correctly. However, I don't know why a server location would cause the program to only fail some of the times. The old program appears to be working smoothly with the same server path.

Oh well, whatever works. At least now I can stop pulling my rapidly thinning hair out.

Thanks for the help,
Nitsua
Aug 12 '08 #5

Post your reply

Sign in to post your reply or Sign up for a free account.