- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try making a test call to ModComp7 using unique values for the arguments passed, then verify that the arguments are what you think they are.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did a variation on your suggestion by trying to change the values of the passed in data on in the DLL only to find the wrong parameters were being updated. I believe they are being passed in just fine but making changes to the values is not working correctly.
Robert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the DLL's I had written before, the parameters all consisted of variables or arrays that were just integer or real(8) types. So I rewrote the DLL to just pass numeric values, thinking that perhaps the strings/characters were causing a problem; however that did not work either.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please show the C# declaration of the Fortran routine and the actual call. Can you reproduce the problem with a Fortran caller? Which argument(s) are being updated incorrectly and with the values of which other arguments? You know about 1-origin vs. 0-origin arrays?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Build a test program in C++ and make a similar call (use same arguments if possible).
If that fails, then you have an interface issue. Look in the IVF documentation under "C interoperability". Get the C++ call working.
If (when) the C++ call succeeds, have C# call a C++ wrapper that calls the Fortran DLL. This may give you a hint as to where the issue resides.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was referring to Fortran arrays numbering elements starting at 1 whereas C and C-like languages start at zero. That doesn't seem to matter here but I couldn't tell earlier.
When the Fortran routine is entered, are the input values what you expect? You should be able to see which Fortran statement changes the value incorrectly. Can you provide a cut down but complete example that demonstrates the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could you please provide a complete solution folder for the C# code? I am unfamiliar with C# and am not sure which of the many project types to select from.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will let Steve experiment with your uploads.
Your C# code is provisioning for ModComp7 to throw an exception. Fortran does not throw exceptions. Though LoadResultsData() may throw an exception.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
The data value problem with the passed arrays could be due to one of the arrays being 2D:
REAL(8), dimension(6,9), INTENT(OUT) :: dll_inpdef
I've found that 2D and multi-dimensional array order is different for Fortran and C languages. I think that Fortran arrays are stored in column order and C# arrays are stored in row order. I need to transpose the array in C# (or declare as the transposed size) before calling Fortran so that the data is arranged as expected. I'm passing arrays by reference between C# and Fortran.
I've found this link useful in the past:
http://www.nag.co.uk/numeric/csharpinfo.asp
Regards,
Greg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Again this may be my inexperience with C# showing, but I am confused by your calling out dll_tol3, dll_maxitn and dll_maxns as being passed by value in the Fortran code, but on the C# side you also have mc_nloads, mc_ar and mc_ndef specified without [] suggesting to me that those are also passed by value. mc_ar in particular is a double, so if C# passes that by value then that will take up two argument list slots and shift the addresses of the following arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, Greg & Jim
Thank you for taking the time to look at my problem and offer suggestions. Regarding Steve's question about the variables, perhaps I am handling these wrong. The intent of the DLL is to pass in all parameter values to the DLL, do some computations, and return the results to the C# program with the parameters dll_evalue, dll_rmse, & dll_msg. So to my thinking only these values need to be passed by reference.
Attached is the entire VS2015 project to test the dll. When the button on the window is pressed the DLL is called and the "results" of dll_evalue is loaded into a datagrid.
Again, thanks for all of the help!
--Robert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The fundamental problem is as I described. You have several arguments declared in the C# code as being passed by value, but on the Fortran side they are declared as passed by reference. This will corrupt the argument passing for any arguments that aren't the same size as an address.
dll_tol3, dll_maxitn, dll_ns, dll_nloads, dll_ar, and dll_ndef all need to be declared as VALUE, not REFERENCE.
The alternative is to use [ref] in the C# declaration for these arguments.
This solved most of the problems. But I am left with dll_rmse (mc_rmse in the C# code.) The argument is declared [out] in C#, which should mean pass by reference, but the address being passed is null. I can't figure out why that is and will leave that as an exercise for a C# expert.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Thanks for the analysis. I have been in meetings so I will implement your suggestions and hopefully it will resolve my problems. I will check out the dll_rmse issue on my end, hopefully it will be a minor problem.
--Robert
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page