- 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
John C. wrote:
Which version of Fortran dll is compatible with c# ASP.NET web application ,something like
http://www.c-sharpcorner.com/UploadFile/1e050f/creating-and-using-dll-cl...Any help Wil be appreciated
@John C.,
Please note a Fortran DLL is similar to a C DLL or an unmanaged (Microsift terminology) C++ DLL.
Look up online on how to interoperate ASP.NET applications with a C DLL or an unmanaged C++ DLL using a P/Invoke layer, etc. the same concepts will apply to the Fortran libraries also.
By the way, look in Quote #2 of the thread below for an example of a .NET application working with Fortran; it's in Visual Basic but the same idea holds for a C# ASP.NET web application too, though with the latter you will likely have to consider thread safety and reentrancy.
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/509148
- 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
Dear @FortranFan I did what you said (on the project as the topic) as same as your link instruction but I got this errors
EntryPointNotFoundException was unhandled
Unable to find an entry point named 'endat3D' in DLL 'C:\Users\admin\Downloads\HW5 add mexfam with DLL VB B\HelloWorld\HelloWorld\electrostatic3D\Debug\electrostatic3D.DLL'.
on this line of code (VB):
Call endat3D( _
strMessage, _
AddressOf RTBDisplayStatus)
this is my vb page:
Option Strict Off
Option Explicit On
Imports System.Text
Imports System.Runtime.InteropServices
Public Class frmHelloWorld
<UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
Public Delegate Sub WriteDelegate(SomeString As StringBuilder, ByRef Irc As Integer)
<DllImport("C:\Users\admin\Downloads\HW5 add mexfam with DLL VB B\HelloWorld\HelloWorld\electrostatic3D\Debug\electrostatic3D.DLL", CallingConvention:=CallingConvention.Cdecl)> _
Public Shared Sub endat3D(MsgString As StringBuilder, _
<MarshalAs(UnmanagedType.FunctionPtr)> fPtr As WriteDelegate)
End Sub
Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
Dim strMessage As StringBuilder
Dim IRC As Integer
strMessage = New StringBuilder("From VB.NET: Hello World")
Call RTBDisplayStatus(New StringBuilder("From VB.NET: Starting Fortran"), IRC)
Call endat3D( _
strMessage, _
AddressOf RTBDisplayStatus)
Call RTBDisplayStatus(New StringBuilder("From VB.NET: Finished Fortran"), IRC)
End Sub
Public Sub RTBDisplayStatus(s1 As StringBuilder, ByRef irc As Integer)
'
'frmHelloWorld.vb / RTBDisplayStatus
'
RichTextBox1.Text += s1.ToString().Trim() & vbCrLf
System.Windows.Forms.Application.DoEvents()
'
End Sub
End Class
and this is my endat3D.f90
!------------------------------------------------------------------------
! DATA INPUT
!------------------------------------------------------------------------
subroutine endat3D( )
use fich_electros3D
use parametros_electros3D
use electros3D
use cargavol
use cargacur
use cargapun
use permitividad
use bloqueo
use derivados3D
use auxiliar_cargas
implicit none
integer :: temp ! Dirichlte/Neumann : number of references per function
! Volumic charges : number of charged domains per function
integer :: fnum ! function numbers: Dirichlet (1 to 7) function(1) == User defined
! Neumann (1 or 3) function(1) == User defined
integer :: temp1 ! input via function for the volumic charge (1 Y 0 N)
integer :: temp2 ! input via array for the volumic charge (1 Y 0 N)
integer :: temp3 ! input via file for the volumic charge (1 Y 0 N)
integer :: i,j
dir%fun = 1
neu%fun = 1
vol%fun = 1
sup%fun = 1
cur%fun = 1
nrn = 0
neuman%numero = 0
nrd = 0
blofron%numero = 0
blopun%numero = 0
carvol%numero = 0
carsup%numero = 0
carcur%numero = 0
ncarpun = 0
permirel%numero = 0
read*,fichma
read*,fichsol
read*,fichgradsol
print*,'Strong imposition of Dirichlet conditions option (1 Yes 0 No)'
read*,iopblo
print*,iopblo
opcion_bloqueo: if (iopblo.eq.1) then
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via function (1 Yes 0 No)'
read*,iopblo1
print*,iopblo1
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via constants in the boundaries (1 Yes 0 No)'
read*,iopblo2
print*,iopblo2
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via punctual blocking (1 Yes 0 No)'
read*,iopblo3
print*,iopblo3
entrada_por_funcion: if (iopblo1.eq.1) then
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via function'
do while (.TRUE.)
print *, 'Number of references'
read*,temp
print*,temp
if (temp <= 0) exit
print *, 'References'
read*,(irefd(i),i=nrd+1,nrd+temp)
print*,(irefd(i),i=nrd+1,nrd+temp)
print *, 'Function associated to the references'
read*, fnum
print*,fnum
dir%fun(nrd+1:nrd+temp) = fnum
if (fnum<1 .or. fnum>7) stop 'incorrect function number'
nrd = nrd + temp
enddo
endif entrada_por_funcion
entrada_por_constantes: if (iopblo2.eq.1) then
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via constants in the boundaries'
print*, 'Number of references'
read*,blofron%numero
print*,blofron%numero
if(blofron%numero.gt.0) then
print*,'References and values'
do i=1,blofron%numero
read*,blofron%referencias(i)
read*,blofron%valor(i)
enddo
print*,(blofron%referencias(i),i=1,blofron%numero)
print*,(blofron%valor(i),i=1,blofron%numero)
endif
endif entrada_por_constantes
entrada_por_puntos: if (iopblo3.eq.1) then
print*, 'Strong imposition of Dirichlet conditions'
print*, 'Input via punctual blocking'
print*, 'Number of points'
read*,blopun%numero
print*,blopun%numero
if (blopun%numero.gt.0) then
print*,'References and values'
do i=1,blopun%numero
read*,blopun%referencias(i)
read*,blopun%valor(i)
enddo
print*,(blopun%referencias(i),i=1,blopun%numero)
print*,(blopun%valor(i),i=1,blopun%numero)
endif
endif entrada_por_puntos
endif opcion_bloqueo
print*, 'Neumann references option (1 Yes 0 No)'
read*,iopneu
print*,iopneu
opcion_neuman: if (iopneu.eq.1) then
print*, 'Neumann references option'
print*, 'Input via function (1 Yes 0 No)'
read*,iopneu1
print*,iopneu1
print*, 'Neumann references option'
print*, 'Input via constants in the boundaries (1 Yes 0 No)'
read*,iopneu2
print*,iopneu2
entrada_por_funcion_neuman: if (iopneu1.eq.1) then
print*, 'Neumann references option'
print*, 'Input via function'
do while (.TRUE.)
print *, 'Number of references'
read*,temp
print *, temp
if (temp <= 0) exit
print *, 'References'
read*,(irefn(i),i=nrn+1,nrn+temp)
print*,(irefn(i),i=nrn+1,nrn+temp)
print *, 'Function associated to the references'
read*, fnum
neu%fun(nrn+1:nrn+temp) = fnum
if (fnum/=1 .and. fnum/=3) stop 'incorrect function number'
print*,fnum,functions(fnum)
nrn = nrn + temp
enddo
endif entrada_por_funcion_neuman
entrada_por_constantes_neuman: if (iopneu2.eq.1) then
print*, 'Neumann references option'
print*, 'Input via constants in the boundaries'
print*, 'Number of references'
read*,neuman%numero
print*,neuman%numero
if (neuman%numero.gt.0) then
print *, 'References and values'
do i=1,neuman%numero
read*,neuman%referencias(i)
read*,neuman%valor(i)
enddo
endif
print*,(neuman%referencias(i),i=1,neuman%numero)
print*,(neuman%valor(i),i=1,neuman%numero)
endif entrada_por_constantes_neuman
endif opcion_neuman
print *, 'Quadrature formula for matrix and second member option'
read*,iop
print*,iop
print *, 'Quadrature formula for the boundary terms'
read*,iopf
print*,iopf
print *, 'Volumic charge option (1 Yes 0 No)'
read*,iopvol
print*,iopvol
if (iopvol.eq.1) then
print*, 'Volumic charge option'
print*, 'Input via function (1 Yes 0 No)'
read*, temp1
print *, temp1
print*, 'Volumic charge option'
print*, 'Input via constants in the domains (1 Yes 0 No)'
read*, temp2
print *, temp2
if (temp1.eq.1) then
do while (.TRUE.)
print *, 'Number of references'
read*,temp
print *, temp
if (temp <= 0) exit
print*,'Domain references'
read*,(carvol%referencias(i), i=carvol%numero+1,carvol%numero+temp)
print*,(carvol%referencias(i), i=carvol%numero+1,carvol%numero+temp)
carvol%valor(carvol%numero+1:carvol%numero+temp)=0.d0
carvol%constante(carvol%numero+1:carvol%numero+temp)=.FALSE.
print*,'Type one of the function numbers below:'
print*,1,': ',functions(1)
print*,2,': ',functions(2)
read*, fnum
vol%fun(carvol%numero+1:carvol%numero+temp) = fnum
if (fnum/=1 .and. fnum/=2) stop 'incorrect function number'
print*,fnum,functions(fnum)
carvol%numero = carvol%numero + temp
enddo
endif
if (temp2.eq.1) then
print*,'Number of charges by constant'
read*,temp
print*,temp
if (temp.gt.0) then
do i=1,temp
print*,'Domain references'
read*,carvol%referencias(carvol%numero+i)
print*,carvol%referencias(carvol%numero+i)
print*,'Charge associated to the domain'
read*,carvol%valor(carvol%numero+i)
print*,carvol%valor(carvol%numero+i)
carvol%constante(carvol%numero+i) = .TRUE.
enddo
carvol%numero = carvol%numero + temp
endif
end if
end if
print*,'Superficial charge option (1 Yes 0 No)'
read*,iopsup
print*,iopsup
if (iopsup.eq.1) then
print*,'Superficial charge option'
print*, 'Input via function (1 Yes 0 No)'
read*,temp1
print*,temp1
print*,'Superficial charge option'
print*, 'Input via constants in the surfaces (1 Yes 0 No)'
read*,temp2
print*,temp2
if (temp1.eq.1) then
do while (.TRUE.)
print*,'Number of surfaces'
read*,temp
print *, temp
if (temp <= 0) exit
print*,'Surface references'
read*,(carsup%referencias(i),i=carsup%numero+1,carsup%numero+temp)
print*,(carsup%referencias(i),i=carsup%numero+1,carsup%numero+temp)
carsup%valor(carsup%numero+1:carsup%numero+temp)=0.d0
carsup%constante(carsup%numero+1:carsup%numero+temp)=.FALSE.
print*,'Type one of the function numbers below:'
print*,1,': ',functions(1)
print*,3,': ',functions(3)
print*,4,': ',functions(4)
read*, fnum
sup%fun(carsup%numero+1:carsup%numero+temp) = fnum
if (fnum/=1 .and. fnum/=3 .and. fnum/=4) stop 'incorrect function number'
print*,fnum,functions(fnum)
carsup%numero = carsup%numero + temp
enddo
endif
if (temp2.eq.1) then
print*,'Number of surfaces'
read*,temp
print *, temp
if (temp.gt.0) then
print *, 'Surface references and associated values'
do i=1,temp
read*,carsup%referencias(carsup%numero+i)
read*,carsup%valor(carsup%numero+i)
carsup%constante(carsup%numero+i) = .TRUE.
enddo
print *, (carsup%referencias(carsup%numero+i),i=1,temp)
print *, (carsup%valor(carsup%numero+i),i=1,temp)
carsup%numero = carsup%numero + temp
endif
end if
end if
print*,'Curvilinear charge option (1 Yes 0 No)'
read*,iopcur
print*,iopcur
if (iopcur.eq.1) then
print*,'Curvilinear charge option'
print*, 'Input via function (1 Yes 0 No)'
read*,temp1
print *, temp1
print*,'Curvilinear charge option'
print*, 'Input via constants in the curves (1 Yes 0 No)'
read*,temp2
print *, temp2
if (temp1.eq.1) then
do while (.TRUE.)
print*,'Number of curves'
read*,temp
print*,temp
if (temp <= 0) exit
print*,'Curve references'
read*,(carcur%referencias(i),i=carcur%numero+1,carcur%numero+temp)
print*,(carcur%referencias(i),i=carcur%numero+1,carcur%numero+temp)
carcur%valor(carcur%numero+1:carcur%numero+temp)=0.d0
carcur%constante(carcur%numero+1:carcur%numero+temp)=.FALSE.
print*,'Type one of the function numbers below:'
print*,1,': ',functions(1)
print*,5,': ',functions(5)
read*, fnum
cur%fun(carcur%numero+1:carcur%numero+temp) = fnum
if (fnum/=1 .and. fnum/=5) stop 'incorrect function number'
print*,fnum,functions(fnum)
carcur%numero = carcur%numero + temp
enddo
endif
if (temp2.eq.1) then
print*,'Number of curves'
read*,temp
print *, temp
if(temp.gt.0) then
print*, 'Curve references and associated charges'
do i=1,temp
read*,carcur%referencias(carcur%numero+i)
read*,carcur%valor(carcur%numero+i)
carcur%constante(carcur%numero+i) = .TRUE.
enddo
print *, (carcur%referencias(carcur%numero+i),i=1,temp)
print *, (carcur%valor(carcur%numero+i),i=1,temp)
carcur%numero = carcur%numero + temp
endif
end if
end if
print*,'Punctual charge option (1 Yes 0 No)'
read*,ioppun
print*,ioppun
if (ioppun.eq.1) then
print*,'Number of charges'
read*,ncarpun
do i=1,ncarpun
print*,'Point coordinates and associated charge'
read*,xcarpun(i)
read*,ycarpun(i)
read*,zcarpun(i)
read*,carpun(i)
print*, xcarpun(i),ycarpun(i),zcarpun(i)
print*, carpun(i)
enddo
end if
iopteta=0
print*,'Number of subdomains'
read*,permirel%numero
do i=1,permirel%numero
print*,'Subdomain number'
read*,permirel%referencias(i)
print*,permirel%referencias(i)
print*,'Relative electric permitivity option'
print*,'1 --> Via function'
print*,'2 --> Via constants per domain'
print*,'3 --> Via array'
read*,permirel%iopermir(i)
print*,permirel%iopermir(i)
if(permirel%iopermir(i).eq.1) then
print*,'Function name'
!do j=1,size(functions_perm,1)
! print *, j,': ', functions_perm(j)
!enddo
read*,permirel%etiqueta(i)
!print*,permirel%fun(i)
if (permirel%fun(i)<1 .or. permirel%fun(i)> &
size(functions_perm,1)) stop 'incorrect function number'
elseif(permirel%iopermir(i).eq.2) then
print*,'Electric permitivity (x,y,z)'
read*,permirel%valorx(i), permirel%valory(i), permirel%valorz(i)
print*,permirel%valorx(i), permirel%valory(i), permirel%valorz(i)
elseif(permirel%iopermir(i).eq.3)then
iopteta=1
read*,permirel%ntab(i)
do j=1,permirel%ntab(i)
read*,permirel%teta(i,j),permirel%valtabx(i,j), &
permirel%valtaby(i,j),permirel%valtabz(i,j)
enddo
else
stop 'Incorrect relative electric permitivity option: only 1 , 2 , 3'
endif
enddo
if (iopteta.eq.1) then
print*,'Name of temperature file'
read*,fichteta
print*,fichteta
endif
print*,'Option for the linear system resolution'
print*,'1: Direct method, 0 : Conjugate gradient'
read*,iopsl
print*,iopsl
if(iopsl.eq.0) then
print*,'Corvengence error in CG'
read* ,epscg
print*,epscg
print*,'Maximum number of iterations in CG'
read*,nitcg
print*,nitcg
endif
if(allocated(ncaras))deallocate(ncaras)
allocate(ncaras(carsup%numero),stat=ierror)
if (ierror.ne.0) then
print*,'Error while allocating ncaras'
stop 1
endif
if(allocated(nodc1))deallocate(nodc1)
if(allocated(nodc2))deallocate(nodc2)
if(allocated(nodc3))deallocate(nodc3)
allocate(nodc1(carsup%numero,ndcaras), &
nodc2(carsup%numero,ndcaras), &
nodc3(carsup%numero,ndcaras),stat=ierror)
if (ierror.ne.0) then
print*,'Error while allocating nodc1,2 o 3'
stop 1
endif
if(allocated(naristas))deallocate(naristas)
allocate(naristas(carcur%numero),stat=ierror)
if (ierror.ne.0) then
print*,'Error while allocating naristas'
stop 1
endif
if(allocated(nod1))deallocate(nod1)
if(allocated(nod2))deallocate(nod2)
allocate(nod1(carcur%numero,ndar), &
nod2(carcur%numero,ndar),stat=ierror)
if (ierror.ne.0) then
print*,'Error while allocating nod1 o nod2'
stop 1
endif
return
end
so what should I do?
best regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It appears to be a simple name decoration issue. By default, the Fortran compiler creates an entry point ENDAT3D regardless of the case used for the name in the Fortran source. VB probably uses a different convention, so the names of the entry expected and the entry present differ in case and/or underscores. There are a number of ways of managing name decoration, ranging from compiler options to embedded DEC$ directives in the Fortran code. Find out what VB expects and make the Fortran match that (I don't use VB, so I don't know what it expects).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
VB is case sensitive and doesn't "decorate" names. Also for 32-bit, VB uses the STDCALL convention by default, but I see you overrode that with Cdecl, so that part is ok.
- 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
- 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:
As @FortranFan said in
https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-fo..... how could I modify @FortranFan project with a little changes that cover my Fortran project ..
@John C.,
You seem to be taking the Visual Basic .NET and Fortran example from the above thread on this forum and literally using the Visual Basic code with only a name change to endat3D and hoping everything works out. It's not as simple as that, at least as far as I know.
It would appear you need to do a lot more research and investigate further because your posts above indicate issues at the very basic (no pun intended!) level: first, you do not seem to have paid attention to make the procedures in Fortran callable in a mixed language environment and whether as part of this, you have even looked into the interoperability aspects with a companion C processor; you do not seem to have looked into the method signatures i.e., matching the procedure declaration in Fortran with the interface in Visual Basic; also, it's unclear if you have setup your Fortran DLL project correctly with the necessary export definitions.
All I can suggest is for you to look up information online and apply the learnings to your situation and note the complete working example of Visual Basic .NET and Fortran from the above thread is a good guide, provided you pay attention to the relevant details:
- Information on setting up of DLLs by Microsoft: https://msdn.microsoft.com/en-us/library/1ez7dh12.aspx
- Also look into DLL example with Intel Fortran: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-using-the-intel-fortran-samples
- Mixed-language programming for Fortran and C: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-mixed-language-programming
- Pay particular attention to standard Fortran interoperability aspects: https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-standard-fortran-and-c-interoperability
- 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
There are two sample applications that mix VB with Fortran that you can find in the samples installed with your compiler version. (In some newer versions the samples are provided online only.) Unpack the samples ZIP file into a writable folder and look under Fortran > MixedLanguage. I don't know what the "stringbuilder" thing does.
- 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
One or many .f90 files makes no difference. What matters is getting the expectations of VB and Fortran to match.
I see that your Fortran code that you want to call "as a DLL" has a main program. That won't work. You have to call a subroutine or a function, so you'll have to restructure the program as a function that can be called. You can test it first by calling from a Fortran main program, and then work out how to interface it to VB.
I suggested the VB-Fortran samples as "case studies" for how to do this sort of thing. You'll see in both programs that there is no Fortran main program - instead there are functions. The VB code determines what data wants to be processed by the Fortran code and calls the Fortran function, which resides in a DLL. The call then returns to VB which does something with the result.
I fear that you think there's a simple edit to your existing program that will make it all work with VB - that is not the case.
- 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
Why don't you test with a very small piece of Fortran code? Why not try the VB-Fortran sample code as Steve has suggested?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Part of what is pasted there is the VB.NET-Safearrays code, which is far more complicated than is needed here. The other sample, VB-Calls-Fortran, is much simpler.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page