Returning an array variable from a .NET dll

1,051 views
Skip to first unread message

Matthew Hodgskiss

unread,
Dec 18, 2008, 6:30:16 AM12/18/08
to mapi...@googlegroups.com

Is it possible to use Mapbasic to return an array from a .NET dll and then assign the returned array to a Mapbasic array?

 

------- mapbasic code --------

 

Dim tmp_sharg_layer_list() as string

 

Declare Method getShargTypes Class "ShargUI.Functions" Lib "ShargUI.dll"  As String
 
 
SUB populate_sharg_list
 
tmp_sharg_layer_list = getShargTypes
 
END SUB
 
 
 
--------- c# code  ---------
 
 

          public static string[] getShargTypes()

            {

                  DataTable dt = SectionDetailForm.PopulateDT("select name from ShargTypes order by TypeID"); // PopulateDT returns DataTable after connecting to an access mdb

                  string[] result = new string[dt.Rows.Count];

                  for (int i=0;i< dt.Rows.Count;i++)

                  {

                        result[i] = dt.Rows[i]["name"].ToString();

                  }

                  return result;

                }
 
 
 
I keep getting the following error message for the MB code shown above
 
“Cannot assign to array or type variable:  tmp_sharg_layer_list”
 
Basically I just want to use .NET to connect to my access database instead of using an attribute-only ODBC connection in Mapinfo.
 
My existing code which works ok looks like this:
 
------------- existing mapbasic code
 
SUB populate_sharg_list
dim I as integer
I = 1
open table applicationdirectory$()+ "qry_DistinctType.tab" as qry_DistinctType
Server Refresh qry_DistinctType
fetch first from qry_distinctType
Do While Not EOT(qry_DistinctType)
redim tmp_sharg_layer_list(I)
tmp_sharg_layer_list(I) = qry_DistinctType.type
fetch next from qry_DistinctType
I = I+1
Loop 
END SUB
 
 
Any advice would be gratefully received 
 
Regards,
 
Matt
 

 

Matt Hodgskiss BSc Msc

GIS Officer

Survey, Cartography & GIS

Engineering Consultancy Services

103 Wellington Road South

Stockport

SK1 3TT

Tel:0161 474 4913

Web: http://www.stockport.gov.uk/ecs

Email:matthew....@stockport.gov.uk

 




**********************************************************************

This email, and any files transmitted with it, is confidential and
intended solely for the use of the individual or entity to whom they
are addressed. As a public body, the Council may be required to disclose this email, or any response to it, under the Freedom of Information Act 2000, unless the information in it is covered by one of the exemptions in the Act.

If you receive this email in error please notify Stockport ICT, Business Services via email...@stockport.gov.uk and then permanently remove it from your system.

Thank you.

http://www.stockport.gov.uk
**********************************************************************

Peter Horsbøll Møller

unread,
Dec 18, 2008, 8:38:28 AM12/18/08
to mapi...@googlegroups.com
Matt,
 
I think you need to send the array from MapBasic to the .NET dll as a parameter to the procedure.
Also you would need to know how big the array should be as you propably can't resize the array inside the .NET dll.
 
Like this (MapBasic):
 
Call getShargTypes(tmp_sharg_layer_list)

 
2008/12/18 Matthew Hodgskiss <matthew....@stockport.gov.uk>

Is it possible to use Mapbasic to return an array from a .NET dll and then assign the returned array to a Mapbasic array?

Peter Horsbøll Møller

Glen

unread,
Dec 20, 2008, 12:43:22 PM12/20/08
to MapInfo-L
2.1 DLL Parameters
Because DLLs are typically written in C, DLLs can use a wide variety
of parameters not directly supported by Visual Basic. As a result,
when passing parameters, the programmer has to find the appropriate
data type to pass.
Passing Arguments by Value or by Reference
By default, Visual Basic passes all arguments by reference. (When
passing by reference, Visual Basic supplies a 32-bit far address.)
However, many DLL functions expect an argument to be passed by value.
This can be achieved by placing the ByVal keyword in front of the
argument declaration.

The following sections show you how to convert parameters to Visual
Basic.
8- to 16-Bit Numeric Parameters
Pass 8- to 16-bit numeric parameters (int, short, unsigned int,
unsigned short, BOOL, and WORD) as Integer.
32-bit Numeric Parameters
Pass 32-bit numeric parameters (long, unsigned long, and DWORD) as
LONG.
Object Handles
All handles are unique 16-bit integer values associated with a Window
and are passed by value, so pass these parameters as Integer.
Strings
Strings include the LPSTR and LPBYTE data types (pointer to characters
or pointer to unsigned characters). Pass these parameters as (ByVal
paramname As String). To pass Visual Basic strings directly, pass them
as (param As String).

For additional information on passing strings between Visual Basic and
a C DLL, please see the following article in the Microsoft Knowledge
Base:
118643 (http://support.microsoft.com/kb/118643/EN-US/ ) How to Pass a
String or String Arrays Between VB and a C DLL
NOTE: Visual Basic strings require special handling, so don't pass
strings directly unless the DLL explicitly requires it.
Pointers to Numeric Values
Pass pointers to numeric values by simply not using the ByVal
keyword.
Structures
If the Visual Basic user-defined type matches the structure expected
by the DLL, the structure can be passed by reference.

NOTE: Structures cannot be passed by value.
Pointers to Arrays
Pass the first element of the array by reference.
Pointers to functions
Visual Basic does not support callback functions, so DLL functions
that have pointers to functions cannot be used with Visual Basic.
Null Pointers
If a DLL expects a Null pointer, pass it as (ByVal paramname As Any).
You can use 0& as the value of paramname when calling the DLL.

Peter Horsbøll Møller

unread,
Jan 6, 2009, 5:15:16 AM1/6/09
to mapi...@googlegroups.com
Matt,
 
Here is a very basic sample of how to have a .NET method return values in an array.
 
In MapBasic:
****************************************************
Include "MapBasic.def"

Declare Sub Main
Declare Method GetValuesInArray  Class "MapBasicTest.Controller"  Lib "MapBasicTest.dll"
   (ByVal numValues As Integer, arrValues() As String)
'----------------------
Sub Main
Dim arrList() As String
Dim i, j As Integer
 
  i = 2
  '**You need to dimension the array before asking .NET to fill it
  Redim arrList(i)
 
  '**Filling the array with values for debug purpose. Not necessary
  For j = 1 To Ubound(arrList)
    arrList(j) = "MapBasic value " & j
  Next
 
  Call GetValuesInArray(i, arrList)
 
  '**Testing the returned values
  For j = 1 To Ubound(arrList)
    Print j & ": " & arrList(j)
  Next
 
End Sub
****************************************************
 
In C#:
****************************************************
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
 
namespace MapBasicTest
{
  public class Controller
  {
    public static void GetValuesInArray(int numValues, string[] list)
    {
      for (int i = 1; i <= numValues; i++)
      {
        MessageBox.Show(string.Format("Before: {0}", list[i - 1]));
        list[i - 1] = string.Format(".NET value {0}", i);
        MessageBox.Show(string.Format("After: {0}", list[i - 1]));
      }
    }
  }
}
 
****************************************************
Note that you should not use the ref keyword in C# when passing arrays.
This is only necessary if you pass "single" variables to C# by-ref.
 
Peter Horsbøll Møller
 
2008/12/18 Peter Horsbøll Møller <mapi...@horsboll-moller.dk>
Reply all
Reply to author
Forward
0 new messages