Passing strings by value
In general, you should avoid passing strings by value to Fortran subroutines that use f90VB facilities, mainly because it would hinder the portability of your Fortran-f90VB code (some Fortran compilers cannot handle arguments passed by value). If you do not expect to change a BString passed to a Fortran subroutine, you can declare the argument with intent(in). Your Visual Basic declaration still passes the BString by reference and the Fortran subroutine also receives the Bstring by reference, but the intent(in) qualifier in your Fortran code will stop you from mistakenly calling any procedure that changes the BSstring handle.
Example 4.3
The following example shows how you can enforce that a string passed as an argument by reference is not modified in a Fortran subroutine. The Fortran procedure receives two string arguments. The first string is an input string. The subroutine returns the second string with the content from the first string converted to uppercase. Note that the Fortran code declares the input string (InBStrHndl) with intent(in) because we do not want to change this argument. The second string is declared with intent(inout), because it will get changed inside the procedure.
This is the code for the Fortran subroutine:
subroutine UpperCaseStr(InBStrHndl,OutBStrHndl)
use f90VBDefs
use f90VBBstrings
implicit none
integer(BSTRHNDL_KIND),intent(in)::InBStrHndl
integer(BSTRHNDL_KIND),intent(inout)::OutBStrHndl
!Convert from VB External BString format to standard BString
call BStrConvFromVB(InBStrHndl,OutBStrHndl)
!Changes case of OutBStrHndl
call StrUCase(OutBStrHndl)
!Convert OutBStrHndl to VB External BString format
call BStrConvToVB(OutBStrHndl)
end subroutine UpperCaseStr
As in Example 4.2, this subroutine will be called from a Visual Basic program, so the content of the input string (InBStrHndl) must be converted to the standard BString format. You do this by calling f90VB's subroutine BStrConvFromVB. Note however, that in this case BStrConvFromVB is requested to return the standard-conforming BString in OutBStrHndl, because InBStrHndl cannot be modified. StrUCase is another f90VB subroutine. It converts to uppercase the contents of a standard BString. BStrConvToVB is called just before returning control to Visual Basic, to convert OutBStrHndl into the special BString format Visual Basic expects for BStrings returned by external subroutines.
To call UpperCaseStr from Visual Basic or Visual Basic for Applications, you need to declare the function as external, and give VB the location of the DLL that contains the procedure. For this you can create a new Visual Basic project and add a module file with the following declaration:
Declare Sub UpperCaseStr Lib "Example43.dll" (InStr As String,
OutStr as String)
You can also add a simple form to request an input string and print the resulting string (Figure 4.4).
To call subroutine UpperCaseStr add the following code to the Click event of the Go! button:
Private Sub cmdGo_Click()
Dim Str As String
Call UpperCaseStr(txtInputStr.Text, Str)
txtOutputStr.Text = Str
End Sub
Figure 4.5 shows an example of the result after entering an input string and clicking the Go! Button.
Some compilers, for example Compaq Visual Fortran and Absoft Pro Fortran, allow the creation of procedures that receive or pass arguments by value. With these compilers, you can enforce the argument intent at the Visual Basic and Fortran levels at the expense of losing portability. For example, using Digital Visual Fortran, subroutine UpperCaseStr could be declared as follows:
subroutine UpperCaseStr(InBStrHndl,OutBStrHndl)
!DEC$ATTRIBUTES DLLEXPORT:: UpperCaseStr
!DEC$ATTRIBUTES STDCALL:: UpperCaseStr
!DEC$ATTRIBUTES ALIAS: 'UpperCaseStr'::UpperCaseStr
!DEC$ATTRIBUTES VALUE :: InBStrHndl
!DEC$ATTRIBUTES REFERENCE :: OutBStrHndl
use f90VBDefs
use f90VBBstrings
implicit none
integer(BSTRHNDL_KIND),intent(in)::InBStrHndl
integer(BSTRHNDL_KIND),intent(inout)::OutBStrHndl
!Convert from VB External BString format to standard BString
call BStrConvFromVB(InBStrHndl,OutBStrHndl)
!Changes case of OutBStrHndl
call StrUCase(OutBStrHndl)
!Convert OutBStrHndl to VB External BString format
call BStrConvToVB(OutBStrHndl)
end subroutine UpperCaseStr
The Visual Basic declaration for the external subroutine would look like this:
Declare Sub UpperCaseStr Lib "Example43bV.dll" (ByVal InStr As String, OutStr As String)