windows - Fejl med fil placering i excel/fortran dll forbindelse

Indlæg af Hanne Mølgaard Plasc

Problem



Platform: WinXP SP2, Intel Fortran 11, Excel 2007


Jeg har problemer med at forbinde en dll-fil med excel.


Dll-filen er forholdsvis enkel:


subroutine FortranCall (r1, num)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, ALIAS:"FortranCall" :: FortranCall
integer, intent(in) :: r1
character(10), intent(out) :: num
!DEC$ ATTRIBUTES REFERENCE :: num

num = ''
write (num,'(i0)') r1 * 2

return
end subroutine FortranCall


bygge med: ifort/nologo/dll Fcall.f90 , og derefter kopieret til 'temp' -katalog på C-drev ( hvordan skriver man en tilbageslag herefter alligevel (undtagen kopiering/indsættelse )? )


og jeg har en Excel-fil med, i Sheet1:


Private Sub CommandButton1\_Click()
Dim r1 As Long
Dim num As String * 10

     r1 = 123
     Call FortranCall(r1, num)

     TextBox1.Text = "Answer is " & num

End Sub


og i Moduel1:


Declare Sub FortranCall Lib "C:	empFcall.dll" (r1 As Long, ByVal num As String)


Når den løber rapporteres en fejl: runtime error 53, filen blev ikke fundet c: \ temp \ fcall.dll


Nogen har nogen anelse om, hvad der kunne være forkert?

Bedste reference


Jeg ved, at dette er et meget gammelt spørgsmål, men jeg kom på tværs af dette problem den anden dag og troede, at jeg kunne svare på eftertiden. Min VBA kode, der kaldte en Fortran DLL, fungerede fint på min computer, men ikke på min chef s eller en andens computer. Problemet endte med at være afhængighed af andre DLL'er, på trods af at du compilerede i 'release' -modus i stedet for 'debug'. Jeg brugte Dependency Walker til at kontrollere afhængighederne i DLL'en på en computer, hvor den ikke ville arbejde , fandt to DLL'er, der følger med intel compileren, der var nødvendige, og distribuerede disse med min egen kompilerede DLL. [11]

Andre referencer 1


Ikke sikker på hvad der kunne være forkert.


Jeg kunne ikke få hænderne på en ifort-kompilator, men jeg prøvede din kode ved at kopiere en tilfældig DLL til Temp-mappen, der specificerede Declar-sætningen. Når jeg kører den, er fejlen jeg får,: 'Kan ikke finde DLL-indgangspunkt FortranCall i C: \ Temp \ RandomDLL.DLL ', hvilket er i overensstemmelse med brugen af ​​den forkerte DLL (det vil sige DLL'en blev fundet, men det gør ikke det med kaldekoden).


Du kan forsøge at erstatte DLL'en du kompilerede med en tilfældig anden DLL og se, om du får den samme fejl. Hvis du gør det, er det et problem med OS-miljøet, ikke kompilatoren.


Dette er nok ikke særlig nyttigt, men kan eliminere en eller to muligheder.


Miljø, jeg brugte:
Vind Vista,
Excel 2003

Andre referencer 2


Du kan forsøge at flytte din DLL til C: \ Windows \ system32 (eller en anden mappe, der er på standardbanen) og ændre Lib -delen til bare "FCall.dll". Det bør fjerne eventuelle uligheder med lokalisering den egentlige fil

Andre referencer 3


Jeg havde det samme problem - super frustrerende!


Jeg havde den samme slags erklæring i Excel VBA:
Erklære Sub FortranCall Lib 'C: \ temp \ Fcall.dll' (r1 Så Lang, ByVal Num As String)


Det fungerede på min computer, men det fungerede ikke på min chefs computer. Alt stavningen af ​​filnavnet og stavespecifikationen var fint. Min DLL blev samlet i Microsoft Visual C ++ 6.0. Problemet var - En almindelig årsag til ' Fil ikke fundet/Runtime fejl 53 'er, at den kaldende applikation ikke kan finde dll' s, som dll i spørgsmålet faktisk afhænger af !!! Jeg gav min chef den DLL, som jeg kompilerede i DEBUG-tilstand - i dette tilfælde bruger DLL masser af andre fejlfindingsversioner af DLL, som ikke almindeligvis findes på almindelige computere. Da jeg gav min chef RELEASE version af DLL fungerede det fint!
Se også:
http://software.intel.com/en-us/forums/showthread.php?t=42472[12]

Andre referencer 4


Nå kan det være alt for sent, men en række spørgsmål at overveje


1) 'Opkaldskonventionen' skal matche korrekt. Dette har flere forskellige aspekter, hvoraf nogle er:


a) Kapitaliseringen eller ej eller blandingen af ​​s/r og Arg navne.


b) At ringe til konventioner. I din kode har du brugt nogle 'mix' af ting og synes at mangle nogle bits.


For eksempel, prøv dette


subroutine FORTRANCALL (R1, NUM)        ! notice capitalisation
!DEC$ ATTRIBUTES DLLEXPORT :: FORTRANCALL   ! notice capitalisation  and default "calling convention" (this varies between compilers)
                    ! but older CVF and Intel compilers default to CDECL, which you can set in your "properties" etc.  
                    ! Its been a while but I think newer IVF have changed to a different default convention
                    ! e.g. if you were doing this, say, in GCC/gFortran, there would be a much longer discussion
integer, intent(in) :: r1
Character(Len=10), intent(out) :: num   ! you might be able to use Character(Len=*) so long as its fixed on the VBA side
!   remove this => !DEC$ ATTRIBUTES REFERENCE :: num

num = ''
write (num,'(i0)') r1 * 2

return
end subroutine FortranCall


På VBA-siden er erklæringen:


Declare Sub FortranCall\_XX Lib "C: ... your path ...Fcall.dll.dll" \_
Alias "FORTRANCALL" (R1 as Long, ByVal NUM As String, ByVal NumLen as Long)


BEMÆRK den ekstra Arg for String len, dette vises kun på VBA-siden, og KUN, når String er bestået ByVal (en hvilken som helst strengstrækning og specielt arrays af strenge er et kæmpe problem ... gennemførligt, men vær forberedt på nogle lektier) .


Også strenge len her følger blot strengen i forhold til Arg position. Men hvis num var placeret tidligere, ville placeringen af ​​NumLen enten være lige efter Arg num eller i slutningen af ​​Arg-listen afhængigt af kaldkonventionen.


Når du opretter en DLL, opretter kompilatoren også ofte en 'Def' -fil. Du behøver ikke have adgang til Def-filen direkte, når du bruger VBA/Fortran. Men i kigger du inde i det viser du den nøjagtige 'navngivningsstil' for, hvad kompilatoren mener, at din s/r skal kaldes. For eksempel med nogle opkald konventioner, def filen kan vise navnet på din s/r som noget lignende
    \_\_fortrancall @ 12


... uanset Def-filer siger, er hvad du skal bruge i VBA-erklæringen Alias ​​'\_\_fortrancall @ 12'


... disse ting kræver en lang diskussion om generel implementering med forskellige kaldkonventioner/kompilatorer.


BTW: Jeg tilføjede '\_XX' udelukkende for at tillade, at den faktiske VBA UDF har det 'oplagte navn', siger FortranCall, eller hvad som helst ... en rimelig vane, hvis du vil gøre meget af dette og især med funktioner osv. , men ikke for vigtigt her.


og VBA-sub bliver:


Private Sub CommandButton1\_Click()
Dim r1 As Long
Dim num As String * 10
Dim numlen as Long

 numlen = 10                ' required string len, can automate via intrinsics etc

 r1 = 123
 Call FortranCall\_XX(r1, num, numlen)   ' notice the extra Arg

 TextBox1.Text = "Answer is " & num     ' you may wish to add Trim() or something in case returned num does not require 10 chars

End Sub


2) Skal du virkelig passere num som en streng? Passing strings mellem VBA og DLL s er en stor dåse af orme. Hvorfor ikke passere num som Double eller noget?


Hvis det skal være en streng, og hvis det er ByVal, så skal du også inkludere strenglængden som ByVal Long på VBA-siden (da i Fortran er streng len en skjult værdi) som vist ovenfor.


Du kan bestå af Ref og med/uden ekstra StringLen, hvis du ved, hvordan brug (Cray) Pointers eller Variants på Fortran siden for at konvertere VBString til Fortran-streng osv. ... en lang lang diskussion.


3) En mere generel og 'bestemt' måde at distribuere/forbinde til en dll er at konvertere XL-arket/modulet til en XLA ... dvs. en tilføjelse. Derefter er XLA og DLL (sædvanligvis) sat i samme Dir, og Addin er tilføjet til Excel via Tools/Addins osv. .. som har browse for at sikre den korrekte sti.


Derefter kan du også ringe dine s/r'er fra enhver arbejdsbog/ark mv., Ikke kun den ene projektmappe.

Andre referencer 5


Jeg havde det samme for nylig med ifort 14, og problemet forsvinder, når jeg kompilerer med


ifort /dll /libs:static /threads


I stedet for bare


ifort /dll


Meddelelsen 'fil ikke fundet' opstår ofte, når DLL'en er afhængig af en anden DLL, som ikke er på systembanen (jeg havde dette med gfortran og en DLL i f.eks. MinGW32 \ bin ). Men jeg fandt sådan en afhængighed her ikke ret underlig.