- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. have some Fortran .f90 files.
2 I installed visual Fortran compiler in visual studio 2015
-
I created library DLL empty project.
-
I added all .f90 and .f files to the project.
5 I compiled the project.
6 now I have myproject.dll file.
7.I created a web application.
8 I try to add myproject.dll to references.
9.I got this error in visual studio environment before compile. :
reference manager: A reference to path//myDLL.dll could not be added.please make sure that the file is accessible,and that is a valid assembly or COM component.
Which project type knows my dll?.is there any error in compile of my dll?therefore what should I do?
Best regards
Link Copied
- 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 want to migrate from VB.Net to C#.These are my codes:
Module1.vb file:
Module Module1 REM Use ByVal to pass strings unless the called routine expects BSTR structures Public Declare Auto Sub electrostatica3D Lib "FCALL.DLL" _ (ByVal DBL_IN() As Double, ByVal STR_IN As String, ByVal DBL_OUT() As Double) End Module
fcall.f90 fortran file:
subroutine electrostatica3D(DBL_IN, STRING_IN, DBL_OUT) use malla_3DP1 use electros3D use external_electros3D use derivados3D use resolucion_sistema_lineal implicit none ! Specify that DLL_ROUT is exported to a DLL ! and that the external name is 'DLL_ROUT' !DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: electrostatica3D !DEC$ ATTRIBUTES ALIAS:'electrostatica3D' :: electrostatica3D REAL(8), INTENT(IN) :: DBL_IN(0:3) CHARACTER(10), INTENT(IN) :: STRING_IN !DEC$ ATTRIBUTES REFERENCE :: STRING_IN ! When VB passes in a "ByVal String", it passes the address ! of a NUL-terminated string, similar to what C would do, ! and no separate length. The REFERENCE attribute tells ! Fortran not to expect a length. In order to use a function ! such as INDEX, we need to supply some maximum length to Fortran ! which should be at least as long as the longest expected string. REAL(8), INTENT(OUT) :: DBL_OUT(4) REAL(8) STRVAL INTEGER IOS, STRLEN integer :: info double precision :: suma integer :: i STRLEN = INDEX(STRING_IN, CHAR(0)) - 1 ! Convert STRING_IN to a double. If we get an error, we'll ! supply 1.0 as a default READ (STRING_IN(1:STRLEN), *, IOSTAT=IOS) STRVAL IF (IOS /= 0) STRVAL = 1.0 DBL_OUT = STRVAL * DBL_IN call arint3D () return end
Form1.vb file:
Public Class Form1 Inherits System.Windows.Forms.Form Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim DBL_IN(4) As Double Dim DBL_OUT(4) As Double Dim MULTIPLIER As String ' Note that in VB, arrays are zero-based. DBL_IN(0) = 1.0 DBL_IN(1) = 2.0 DBL_IN(2) = 3.0 DBL_IN(3) = 4.0 MULTIPLIER = "2.0" Call electrostatica3D(DBL_IN, MULTIPLIER, DBL_OUT) TextBox1.Text = DBL_OUT(0) TextBox2.Text = DBL_OUT(1) TextBox3.Text = DBL_OUT(2) TextBox4.Text = DBL_OUT(3) End Sub
use C# code as :
using System; using System.Runtime.InteropServices; namespace Console_use_integrate{ class Program { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate float ActionRefInt(ref float n); public ActionRefInt callbackHandler; public Program() { callbackHandler = new ActionRefInt(square); } public float square(ref float n) { return n*n; } static void Main(string[] args) { Program myProg2 = new Program(); float a = 1f; float b = 3f; int step = null; float result; Console.WriteLine("Interval from {0} to {1} ", a, b); result = integrate_Dll(myProg2.callbackHandler, a, b, System.IntPtr.Zero) Console.WriteLine("integration result is {0}",result); Console.ReadKey(); } [DllImport(@"FCALL.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "electrostatica3D")] public static extern float electrostatica3D([MarshalAs(UnmanagedType.FunctionPtr)] ActionRefInt callBack, float a, float b, ref int c); [DllImport(@"FCALL.DLL", CallingConvention = CallingConvention.Cdecl, EntryPoint = "electrostatica3D")] public static extern float electrostatica3D([MarshalAs(UnmanagedType.FunctionPtr)] ActionRefInt callBack, float a, float b, System.IntPtr c); } }
and changing
float a, float b, System.IntPtr c
to something like below but in C# format
ByVal DBL_IN() As Double, ByVal STR_IN As String, ByVal DBL_OUT() As Double
and a little modification maybe needed.
so what should I do?
I found a link maybe it's useful Converting FORTRAN code to C# https://www.codeproject.com/Questions/491373/ConvertingplusFORTRANpluscodeplustoplusCRegards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would suggest asking in a C# forum. Your question isn't really about Fortran. There is probably not a lot of VB/C# expertise here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John C. wrote:
I want to migrate from VB.Net to C#. These are my codes ..
@John C.,
I think it will get quite wordy and rather difficult for anyone trying to explain what you should do to migrate to C#. Already this post and this thread has become too long for me.
You keep pursuing an approach where "a little modification" may be all that is needed to do what you want - in my opinion, this is entirely inappropriate and also inadequate. .NET development is an area for which there are lots and lots of resources available, including free ones online as you have found, and if you are unwilling to parse those resources and apply the learnings from them by yourself for your own needs or unable to do so on account of time or inclination or whatever, you should look to outsource the work to some IT business perhaps e.g., contract programmer(s). Moreover your questions and needs have more to do with .NET than Fortran and so you should turn to MSDN-type of forums with a focus on .NET and P/Invoke for your needs, as suggested by Steve Lionel upthread.
To make it a little easier in your pursuit, attached find an attachment of a zip file with an example of a C# Windows Form application that utilizes a Fortran DLL on the backend to do some calculations. It is based on Visual Studio 2017 with Intel Fortran compiler 18.0 beta update 1; you can figure out how to use this example with your version of Visual Studio and the Fortran compiler. There is little to no documentation by the way in the example, it is deliberate for my expectation is anyone who has made some attempts to learn Fortran and C and also to review .NET development will be able to use this as a rough guide for their needs which is all this is meant for, a crude go-by. The example is based loosely on your previous post but it uses a few code constructs that are somewhat different, it assumes certain things, and it does require a wee bit of attention. Anyone with an eye for a bit of detail though should be able to change or extend it for their needs, especially considering the wealth of information on ,NET online.
The code in Fortran is structured to interoperate with a companion C processor and to accept a double precision floating point input as value along with a multiplier in a C-style string 'char *' format and it parses the info to return a result that is the product of the two. The project in the Visual Studio solution is configured to build a DLL and it does a post-build event to copy the DLL file to TESTPATH, an environment variable pointing to a folder on the Windows PATH.
module m use, intrinsic :: iso_c_binding, only : c_char, c_int, c_double, c_ptr, c_f_pointer implicit none contains subroutine Fsub( inval, ptr_s, lens, outval, fstat ) bind(C, name="Fsub") ! Argument list real(c_double), intent(in), value :: inval type(c_ptr), intent(in), value :: ptr_s integer(c_int), intent(in), value :: lens real(c_double), intent(inout) :: outval integer(c_int), intent(inout) :: fstat fstat = 0 if (lens <= 2) then fstat = 1 return end if blk: block character(kind=c_char, len=lens), pointer :: s_ptr => null() real(c_double) :: mult integer :: istat character(len=10) :: fmtstr character(len=256) :: imsg call c_f_pointer( cptr=ptr_s, fptr=s_ptr ) write ( unit=fmtstr, fmt="(*(g0))", iostat=istat ) "(G", lens, ".", lens-2, ")" if ( istat == 0 ) then read ( unit=s_ptr, fmt=fmtstr, iostat=istat, iomsg=imsg ) mult end if s_ptr => null() if ( istat /= 0 ) mult = 1.0_c_double outval = inval*mult end block blk return end subroutine Fsub end module m
The project in C# is configured as a Windows Form application, it has a static class that helps interoperate with the Fortran DLL as follows:
using System; using System.Runtime.InteropServices; namespace WinFormsApp { static class Fdll { // Overload methods for the optional parameter [DllImport("Fdll.dll", CallingConvention = CallingConvention.Cdecl)] internal static extern void Fsub(double val, System.IntPtr ptrmult, int lens, ref double result, ref int fstat); } }
The project includes all the wiring toward a user-interface (UI), explanations for which can be found in many, many places online; the primary code for a button-driven action to invoke Fortran code for the calculation is:
private void btnCalc_Click(object sender, EventArgs e) { var irc = System.Windows.Forms.DialogResult.None; if (!tbval_valid) { irc = MessageBox.Show("Enter valid numeric input for Value", "Field Value", MessageBoxButtons.OK); tbVal.Select(0, 0); tbVal.Focus(); return; } if (!tbmult_valid) { irc = MessageBox.Show("Enter valid numeric input for Multiplier", "Field Multiplier", MessageBoxButtons.OK); tbVal.Select(0, 0); tbMult.Focus(); return; } System.IntPtr ptr_to_smult = System.IntPtr.Zero; try { tbOut.Text = string.Empty; result = 0.0; string smult = mult.ToString(fmt_mult); ptr_to_smult = Marshal.StringToHGlobalAnsi(smult); int fstat = 0; Fdll.Fsub(val, ptr_to_smult, smult.Length, ref result, ref fstat); if (fstat == 0) { tbOut.Text = Convert.ToString(result); } else { irc = MessageBox.Show("Fsub procedure in the Fortran DLL returned an error: fstat = " + fstat.ToString(), "Button Calculate", MessageBoxButtons.OK); } } catch (Exception ex) { irc = MessageBox.Show(ex.Message, "Button Calculate", MessageBoxButtons.OK); } finally { if (ptr_to_smult != System.IntPtr.Zero) Marshal.FreeHGlobal(ptr_to_smult); } }
Upon execution, the program generates a form
and the user can manipulate the fields and controls as appropriate to work the application.
One can now review ASP.NET material online and modify this example to build an ASP.NET web application.
- 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
John C. wrote:
.. Would you please make changes that I could use your project in Visual studio 2012 and Intel.Parallel.Studio.XE.2016. ..
@John C.
I do not have "Visual studio 2012".
Please do not address me any further in any of your posts.
- 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
Parallel Studio 2018 is still in beta, and may be released in September 2017. However, you probably do not need it (yet). Just install Parallel Studio (or Composer) 2017 Update 4 for now.
- 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
You can't do this in Visual Studio. Windows looks for DLLs in the following locations:
- Current directory (for a VS project that's the project directory)
- Directory where the EXE resides
- Directories named in the PATH environment variable
- The Windows directory
- The Windows\System32 directory
Yes, the DLL path is important.
- 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
That means DLL1.dll does not include a subroutine or function named 'electrostatica3D'.
To enable the .exe to find the DLL when it's not in the same directory as the .exe, add the location of the DLL to the environmental variable PATH. If you don't know how to do this, google it. You can't expect people here to answer every little question, when it's quite feasible for you to find the answer yourself.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John C. wrote:
.. I run above uploaded project in visual studio 2017 and parallel studio 2017.I got this error when I start the project:
Severity Code Description Project File Line Suppression State
Error error PRJ0019: A tool returned an error code from "Performing Post-Build Event..." (F = file, D = directory)? Project.. What should I do non getting this error and the project access DLL automatically (Not manually as I do)? ..
Quote #25 above with the attachment and details on the C# example also included the statement
"The project in the Visual Studio solution is configured to build a DLL and it does a post-build event to copy the DLL file to TESTPATH, an environment variable pointing to a folder on the Windows PATH."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I use these lines of code:
! YOUR CODE HERE module me use, intrinsic :: iso_c_binding, only : c_char, c_int, c_double, c_ptr, c_f_pointer implicit none contains subroutine elecx( ) bind(C, name="elecx") ! YOUR CODE HERE start !program ppalelectros3D use fich_electros3D use electros3D use cargavol use cargacur use cargapun use permitividad use bloqueo use derivados3D use malla_3DP1 use external_electros3D use module_writeVTU use comprobaciones use module_convers use module_fem_extract use module_conver3d, only: conver3d use LIB_VTK_IO_READ use module_readUNV use module_compiler_dependant implicit none integer :: i,istat, p, nnod,DIMS,LNN,LNV,LNE,LNF,nnd,nco,npieces,nverteta,iformat integer, allocatable :: nn(:,:) real(real64), allocatable :: evtun(:) !--------------------------------------------------------------------------- ! INPUT DATA !--------------------------------------------------------------------------- if (command_argument_count() == 0) then call endat3D() else call readxml() end if ! INPUT DATA VERIFICATION, FOR ENDAT & READXML if (.not. comprueba()) then write(error_unit,*) 'Input data check failed' stop 1 else write(output_unit,*) 'Input data check passed' endif call calculate_funs() ! 0.0 IS ASSIGNED TO THE LAST VERTEX IN CASE OF NOT HAVING DIRICHLET CONDITIONS if (blocking_node() < 0) then write(error_unit,*) 'Error assigning blocking node' stop 1 endif !--------------------------------------------------------------------------- ! ELECTROMAGNETIC MESH READING !--------------------------------------------------------------------------- call calindc(indc,inda) p = index(fichma, '.', back=.true.) if (p == 0) stop 'Mesh file has not extension: unable to identify mesh format' select case (lcase(fichma(p+1:len_trim(fichma)))) case('mfm') iformat=1 call leema3D(iformat) case('mum') iformat=2 call leema3D(iformat) case('unv') call readUNV(fichma,nel,nnod,nver,dims,LNN,LNV,LNE,LNF,nn,mm,nrc,nra,nrv,z,nsd) call conver3d(nel, nver, mm, z, nemm, det, binv, ib, jb) case default stop 'Unrecognized mesh file extension' end select call alloc_after_mesh() !--------------------------------------------------------------------------- ! TEMPERATURE READING !--------------------------------------------------------------------------- if (iopteta == 1) call leetmp() !--------------------------------------------------------------------------- ! COMPUTATIONS !--------------------------------------------------------------------------- if (iopblo.eq.1.and.iopblo1.eq.1) then call calprebloqueof(nrd,irefd) endif if (iopblo.eq.1.and.iopblo2.eq.1) then call calprebloqueoc(blofron%numero,blofron%referencias) endif call electrostatica3D() if(allocated(vexac))deallocate(vexac) allocate(vexac(nver),stat=ierror) if (ierror.ne.0) then print*,'Error while allocating array vexac',nver stop 1 endif if(allocated(err))deallocate(err) allocate(err(nver),stat=ierror) if (ierror.ne.0) then print*,'Error while allocating array err',nver stop 1 endif ! call wrtcmp(nver,sol,10,fichsol) ! call writeVTU(nel,nver,mm,z,'tetra',sol,'solucion','scalar', & ! 'node',trim(fichsol)//'.vtu') ! -1: mixed functions ! 0: no data ! 1: User defined / Function defined by user ! ... if (dir%funs > 1.or.& neu%funs > 1.or.& vol%funs > 1.or.& sup%funs > 1.or.& cur%funs > 1) then do i=1,nver vexac(i) = fexac(z(1,i),z(2,i),z(3,i)) err(i) = dabs(vexac(i)-sol(i)) enddo if (dir%funs == 7) then ! 'Example 6' vexac(376) = sol(376) vexac(193) = sol(193) err(193) = dabs(vexac(193)-sol(193)) err(376) = dabs(vexac(376)-sol(376)) elseif (dir%funs == 6) then ! 'Example 5' vexac(1292) = sol(1292) err(1292) = dabs(vexac(1292)-sol(1292)) endif call norl2_3D(sol,xnorexac) call norl2_3D(vexac,xnorexac) call norl2_3D(err,xnorerr) rel = xnorerr/xnorexac print*,'Relative error (%)',100*rel endif ! COMPUTATION OF THE ELECTRIC FIELD call ef() !--------------------------------------------------------------------------- ! RESULTS OUTPUT !--------------------------------------------------------------------------- call wrtcmp(nver,sol,10,fichsol) call writeVTU(nel,nver,mm,z,'tetra',sol,'Potential (V)','scalar', & 'node',trim(fichsol)//'.vtu') call wrtcmpv(nel,e,10,fichgradsol) if(allocated(evtu))deallocate(evtu) allocate(evtu(3*nel),STAT=istat) if (istat.ne.0) stop 'Error while allocating evtu in principal' evtu(1:nel*3:3)=e(1,1:nel) evtu(2:nel*3:3)=e(2,1:nel) evtu(3:nel*3:3)=e(3,1:nel) call cell2node(nver, mm, evtu, evtun) call writeVTU(nel,nver,mm,z,'tetra',evtun,'Electric field (V/m)',& 'vector','node',trim(fichgradsol)//'.vtu') deallocate(evtu,STAT=istat) if (istat.ne.0) stop 'Error while deallocating in principal' deallocate(sol,STAT=istat) if (istat.ne.0) stop 'Error while deallocating in principal' deallocate(e,STAT=istat) if (istat.ne.0) stop 'Error while deallocating in principal' stop 'End of the execution' !end ! YOUR CODE HERE End return end subroutine elecx end module me
there is no Error and everything works right but when I run my program I got this Run time errors:
so what's the reason?
regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's telling you that there was a read error at line 46 of felec.f90. Since you don't provide the code for felec.f90, there's no way for anybody here to know what caused the error.
- 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
Is it reading from the console?
Console applications have a console (obviously) but not so obvious is the fact that DLLs do *not* have a console by default.
You can use AllocConsole to create one, which may or may not be the right thing for your application. By that I mean, depending on what is being READ, then maybe the answer is to use a file for this case? We can't know.
--Lorri
- 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
John -
I found your "endat3d" program in a previous reply, and yes, it clearly reads from the console.
In the DLL you do not have a console, unless you have created it, and that is why you are getting the error.
Perhaps you should always call readxml, and not call endat3d.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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