Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29283 Discussions

Call subroutine defined inside interface block

haitao
Novice
561 Views

Hello,

The following code is from 'DF98SAMPLESMIXLANGVBCALLBACK' of CVF.

subroutine dll_rout(int_arg,str_in,cbproc1,cbproc2,cbproc3)
!dec$ attributes dllexport ::dll_rout
!dec$ attributes alias :'dll_rout'::dll_rout
use dfcom

! Define interface blocks for each of the callback routines
interface
subroutine cbproc1(c1, i1)
pointer (c1, foo1)
character *(200) foo1
integer*4 i1
end

subroutine cbproc2(c1)
pointer (c1, foo1)
character *(20) foo1
end

subroutine cbproc3(i1)
integer*4 i1
end
end interface

! Define the parameters passed to this routine
integer int_arg
character *(*) str_in

character *25 str_out
integer temp
character *5 int_str

! The following paradigm is used for interfacing to the ConvertStringToBSTR
! routine. The string created is Unicode, which is 16 bit. CHARACTER is
! 8 bit, and so an array of INTEGER*2 are used instead of an array of
! CHARACTERs.
pointer (p1, my_str_in)
pointer (p2, my_str_out)
integer*2 my_str_in(25)
integer*2 my_str_out(25)
integer i

! Multiply the value passed by 10, and give it to cbproc3
temp = int_arg * 10
call cbproc3(temp)

! Convert the integer to string, and append it to the string passed,
! and then give it back to cbproc2 as a BSTR
write(int_str,'(i5.5)')int_arg
str_out = str_in // int_str
p2 = ConvertStringToBSTR(str_out)
call cbproc2(p2)

! Create our message, and pass both it and the original integer to cbproc1
p1 = ConvertStringToBSTR("Fortran says Hello!")
call cbproc1 (p1, int_arg)


! Clean up after ourselves
call SysFreeString(p1)
call SysFreeString(p2)

return
end

The code works fine when called from vb.

My question is how to call the procedure cbproc1 from outside the subroutine dll_rout in fortran. For example, I add a line Call SubTest in dll_rout,

subroutine dll_rout(int_arg,str_in,cbproc1,cbproc2,cbproc3)
.
Call SubTest
.
return
end


subroutine SubTest()
Call cbproc1(1, 2)
return
end

and needto call cbproc1 in SubTest.

The compiler gave me the error message:

callback.obj : error LNK2001: unresolved external symbol _CBPROC1@8
Debug/callback.dll : fatal error LNK1120: 1 unresolved externals

What I want to do is send back the fortran calculated results from a lot of subs called by the main sub.

Thanks in advance for any help,

hhtlib

0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
561 Views

As with any dummy argument, once you pass it as an argument, symbol cbproc1 is just a synonym/alias/placeholder for a routine defined elsewhere, and which is an actual argument to dll_rout. That means you have to define it to be an dummy argument of any routine that may call it (i.e. SubTest):

call SubTest(cbproc1)
...
subroutine SubTest(cbproc1)
interface
subroutine cbproc1(...)
...
end subroutine
end interface
call cbproc1(...)
end subroutine

If you need it in many places, there's another non-standard mechanism (Cray pointers to procedures) supported only by CVF/IVF, which enables such routines tobecome "global":

module imports

interface
subroutine cbproc1(...)
...
end subroutine
end interface
pointer(p_cbproc1, cbproc1)

end module imports

subroutine dll_rout(acbproc1...)
use imports
external acbproc1
p_cbproc1 = loc(acbproc1)
call SubTest
...
subroutine SubTest
use imports
call cbproc1(...)
end subroutine

I'd really recommend standard method 1) unless the passing dummy arguments around become really awkward.

Jugoslav

0 Kudos
haitao
Novice
561 Views

Got it.

Thanks so much.

hhtlib

0 Kudos
Reply