Sample Microsoft Visual Basic .NET Projects Illustrating How to Call the NAG C LibraryThis 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).IntroductionSupport 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
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;C:\Program Files\NAG\CL08\ cldll084zl\MKL_ia32_8.0\bin;<rest of path> Techniques Used in the ExamplesArrays 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 SubThe 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 iOr, 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 iA 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 jSee 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. |
© 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