NAG Logo
Numerical Algorithms Group

Sample Microsoft Visual Basic .NET Projects Illustrating How to Call the NAG C Library

This web page contains links to several zip files, each containing a Microsoft Visual Basic .NET project showing how to call a NAG C Library function. These projects have been built and tested under Visual Studio .NET 2003 and also tested with Visual Studio 2005. They should run as-is under Visual Studio .NET 2003. To run these projects under Visual Studio 2005, use the Visual Studio conversion wizard to convert the project. This will update the .sln and .vbproj files; the VB code itself should remain the same. There are separate examples showing how to call the Library from Visual Basic 6 (VB6) and from Excel using Visual Basic for Applications (VBA).

Introduction

Support files for Visual Basic .NET (VB.NET) may be found under the VB.NET skeletons page. These files can be used in VB.NET code. Separate VB6/VBA skeletons are available.

For each user-callable NAG C Library function there is a file called <function name>_skeleton.vb which contains the VB declaration of the C function and all Enum and Structure (Type) declarations necessary for the parameters (mandatory and optional). This file can be imported into your VB project. If more than one NAG C Library function is called, more than one skeleton may be imported, but multiple declarations must be deleted. In the case of closely related functions it may be easier to import one skeleton in its entirety and only paste the declaration of the second and subsequent functions.

The skeleton files are based on the stand-alone version of the NAG C Library DLL (CLDLL084Z_nag.dll); to specify the version of the DLL which uses the MKL BLAS/LAPACK instead (CLDLL084Z_mkl.dll), replace CLDLL084Z_nag.dll by CLDLL084Z_mkl.dll in the Function or Sub declaration.

The support file nag_errlist.vb contains VB code setting the value of all NAG C Library error codes. This file can be imported into your VB project.

Note that unlike VB6, VB.NET does not support "Option Base 1", so all arrays start at 0.

Remember also that to be able to use the NAG C Library DLL, its location will need to appear somewhere in your current path. If the DLL is in C:\Program Files\NAG\CL08\cldll084zl\bin (for example), then your PATH environment variable must contain this folder before starting Visual Basic. If you are using the MKL-based version of the NAG C Library (CLDLL084Z_mkl.dll), then the folder containing the MKL DLLs should also be on your path, but should appear later in the path than the bin folder for the NAG C Library DLLs, e.g.

C:\Program Files\NAG\CL08\cldll084zl\bin;C:\Program Files\NAG\CL08\
cldll084zl\MKL_ia32_8.0\bin;<rest of path>

Techniques Used in the Examples

Arrays

In the NAG C Library function declarations, arrays are declared only with their type. To pass a VB array to the C Library simply pass the first element with the ByRef qualifier; VB.NET passes its address. Under VB.NET, arguments are passed by value by default, so ByRef must be specified.
Declare e04ccc(... ByRef x As Double, ...

Call e04ccc(... x(0), ...
(Note that, for clarity, the declarations in the skeleton files specify "ByVal" explicity, especially since this is a change in the default behaviour from VB6.)

Call-back Functions

In the VB.NET declarations of NAG C Library functions and subroutines, call-back function dummy arguments are declared as delegates.
E.g.
Delegate Function D01SJC_F_DELEGATE ( _
  ByVal x As Double, _
  ByRef comm As Nag_User _
) As Double

Declare Sub d01sjc Lib "CLDLL084Z_nag.dll" ( _
  ByVal f As D01SJC_F_DELEGATE, _
  ...
The pointer to the actual function is passed using the VB AddressOf operator.
E.g.
Call d01sjc(AddressOf fun1,...

Please see the d01sjc and e04nfc examples for examples of call-back functions.

Array Arguments to Call-back Functions

The supplied files contain skeletons for call-back functions. Because the underlying library is written in C, array arguments are simply declared as the appropriate type, and passed by reference. VB.NET passes arguments, by default, by value, so ByRef must be specified here. Hence we have access to a pointer to the array. In the case of input array arguments, the appropriate amount of storage has to be copied to a VB array before it can be used. At the end of the function, output arrays must be copied back to the pointer.

In the examples, the Windows function RtlMoveMemory is used to do this copying. This function may be overloaded to cater for different source and destination types, e.g.

Declare Sub RtlMoveMemory Lib "kernel32" (ByRef hpvDest As Double, _ 
    ByVal hpvSource As IntPtr, ByVal cbCopy As Integer)
Declare Sub RtlMoveMemory Lib "kernel32" (ByVal hpvDest As IntPtr, _
    ByRef hpvSource As Double, ByVal cbCopy As Integer)
Declare Sub RtlMoveMemory Lib "kernel32" (ByRef hpvDest As Nag_Comm, _
    ByRef hpvSource As Nag_Comm, ByVal cbCopy As Integer)

Here is an example of how to do this in a user supplied function called objfun.

Sub objfun(ByVal n As Integer, ByVal ptr_x As IntPtr, ...
' Declare x as an array
Dim x() As Double
' Re-dimension it the right size
ReDim x(n - 1)
' Copy from the pointer ptr_x to our local array
Call RtlMoveMemory(x(0), ptr_x, n * Len(x(0)))
' The array x can now be used.

...

' If x is updated, copy it back to the pointer ptr_x
Call RtlMoveMemory(ptr_x, x(0), n * Len(x(0)))

Examples of how to handle arrays in call-back functions can be found in e04nfc.

C Library Typedefs and VB.NET Structures

Assigning pointers in VB.NET Structures

Pointers in the VB.NET structures defined for the NAG C Library are declared as IntPtrs. In order to assign, for example, a VB Double array to such a pointer, code such as the following may be used.
<StructLayout(LayoutKind.Sequential)> Structure Nag_User
    Dim p As IntPtr
End Structure
...
Dim comm_array(3) As Double
Dim comm As Nag_User
Dim gch As GCHandle  'need to import System.Runtime.InteropServices for this
Dim array_addr As IntPtr
...
gch = GCHandle.Alloc(comm_array, GCHandleType.Pinned)
array_addr = gch.AddrOfPinnedObject()
comm.p = array_addr

The garbage collector handle (GCHandle) provides a means of accessing a managed object from unmanaged memory. A pinned handle is generated to prevent the garbage collector from moving the object. The AddrOfPinnedObject method can then be used to get a stable pointer to the object. In this way, the address of the array can be assigned to the pointer p within the Nag_User structure.

To access the array pointer stored in the VB structure we again use RtlMoveMemory. The declaration required here is

Declare Sub RtlMoveMemory Lib "kernel32" (ByRef hpvDest As Double, _
    ByVal hpvSource As IntPtr, ByVal cbCopy As Integer)

Note that, in this case, the source pointer is passed by value as an IntPtr, and the destination local array is passed by reference as a Double. If the array is to be passed back, the types (and passing conventions) of the first two arguments to RtlMoveMemory are reversed:

Declare Sub RtlMoveMemory Lib "kernel32" (ByVal hpvDest As IntPtr, _
    ByRef hpvSource As Double, ByVal cbCopy As Integer)

In, for example, a user supplied function this array may be accessed by first copying it to a VB array. If the array is updated it must then be copied back.

Dim mycomm(3) As Double  '4 elements
' Copy from pointer to local array
Call RtlMoveMemory(mycomm(0), comm.p, 4 * Len(mycomm(0)))
...
' Copy back from local array to pointer
Call RtlMoveMemory(comm.p, mycomm(0), 4 * Len(mycomm(0)))

Use of such an array is illustrated in the d01sjc and e02bac examples.

Assigning function pointers in VB.NET Structures

The function pointer is declared as a delegate passed by value. For example:
Delegate Sub PRINT_FUN_DELEGATE( _
  ByRef p1 As Nag_Search_State, _
  ByRef p2 As Nag_Comm _
)
...
Sub set_print_fun(ByVal ptr_fun As PRINT_FUN_DELEGATE, _
                  ByRef options As Nag_E04_Opt)
    options.print_fun = ptr_fun
End Sub
The call to this function uses the AddressOf operator to pass the address of the user-defined function, called monit in this example.
Call set_print_fun(AddressOf monit, options)
This usage is illustrated in the e04ccce code within the Misc Functions example.

Strings

Internally VB uses Unicode ("wide") characters, whereas the NAG C Library uses ASCII. VB handles the conversion from Unicode to ASCII for function/subroutine arguments but not for strings in structures. For consistency all C strings are declared as Byte arrays in the VB skeletons. VB strings need to be copied to and from these byte arrays.

To copy a C null terminated string to a VB String, e.g. the fail.message Byte array in the NAG error structure:

Dim msg As New StringBuilder
Dim i As Integer
...
For i = 0 To NAG_ERROR_BUF_LEN - 1
    If (fail.message(i) = CByte(0)) Then Exit For
    msg.Append(Chr(fail.message(i)))
Next i
Or, to copy a VB string to an optional Byte array parameter to a NAG C Library function:
Dim filename As String
Dim i, flen As Integer
...
flen = Len(filename)
filename = "C:\e04ccce_output.r"
For i = 1 To flen
    ' Copy VB string to Byte array.
    options.outfile(i - 1) = CByte(Asc(Mid(filename, i, 1)))
Next i
A pointer to a null terminated string returned from a C Library function can be processed using the PtrToStringAnsi method of the Marshal class:
Dim testnum As Integer
Dim strptr As IntPtr
Dim retstr As String
...
strptr = x04nbc(testnum)
retstr = Marshal.PtrToStringAnsi(strptr)
Or for a function with an array of pointers to strings as an output parameter, code such as the following could be used:
Dim j, maxip As Integer
Dim model_ptr_array() As IntPtr
Dim model_str() As String
...
For j = 0 To maxip - 1
    model_str(j) = Marshal.PtrToStringAnsi(model_ptr_array(j))
Next j
See various routines within the Misc Functions project for examples of these.

Console Window

A number of NAG C Library functions, by default, create a console window to display intermediate results, etc.

At Mark 8 of the NAG C Library DLLs, the console window is implemented differently from in previous Marks of the Library. The console window may be closed temporarily (until more output arrives) via File | Close or permanently (until the next time the application is invoked) via File | Exit. Closing the console window from the close button ("X") in the top right hand corner or via Alt-F4 has the same effect as File | Close. (Unlike the console window in earlier Marks of the NAG C Library DLLs, closing this window will not shut down the parent application and the use of FreeConsole to dismiss the window is no longer necessary.) There are also cut, copy and paste facilities available via the Edit menu.

(The Excel/VBA e04ucc example uses this feature.)

Alternatively, this output may be redirected to a file, as may be seen in the e04ccc example within the Misc Functions project, or suppressed entirely as may be seen in the e04nfc example.

© The Numerical Algorithms Group 2008
Privacy Policy | Trademarks

© Numerical Algorithms Group

Visit NAG on the web at:

www.nag.co.uk (Europe and ROW)
www.nag.com (North America)
www.nag-j.co.jp (Japan)

http://www.nag.co.uk/numeric/CL/classocinfo/VisualBasic.NET/README.asp