Microsoft KB Archive/841293

= How to pass an array between a Visual Basic .NET or Visual Basic 2005 application and a Visual C++ .NET or Visual C++ 2005 function =

Article ID: 841293

Article Last Modified on 11/16/2007

-

APPLIES TO


 * Microsoft Visual Basic 2005
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft Visual C++ 2005 Express Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition
 * Microsoft Visual C++ .NET 2002 Standard Edition

-





SUMMARY
''This article describes how to pass an array from a Microsoft Visual Basic .NET application to a function in a DLL that was created by using Microsoft Visual C++ .NET. This article discusses how to pass an array to a function in any one of the following Visual C++ .NET DLLs:''


 * Microsoft .NET Framework assembly
 * Win32 DLL
 * Component Object Model (COM) DLL

This article contains code samples for passing an integer array from a Visual Basic .NET console application to a function in a .NET Framework assembly, in a Win32 DLL, and in a COM DLL.



IN THIS TASK

 * INTRODUCTION
 * Requirements
 * Create a Visual Basic .NET application
 * Pass an array to a function in a .NET Framework assembly
 * Create an assembly by using Visual C++ .NET
 * Write a Visual C++ .NET function that expects an array
 * Call the function in the .NET Framework assembly
 * Pass an array to a function in a Win32 DLL
 * Create a Win32 DLL by using Visual C++ .NET
 * Write a Visual C++ .NET function that expects a pointer to an array
 * Call the function in the Win32 DLL
 * Pass an array to a function in a COM DLL
 * Create a COM DLL by using Visual C++ .NET
 * Write a Visual C++ .NET function that expects a SAFEARRAY
 * Call the function in the COM DLL
 * Verify that your project works
 * REFERENCES



INTRODUCTION
This step-by-step article describes how to pass an array from a Visual Basic .NET or Visual Basic 2005 application to a function in a DLL that was written by using Visual C++ .NET or Visual C++ 2005. Visual C++ .NET and Visual C++ 2005 support both managed code and unmanaged code. You can use Visual C++ .NET or Visual C++ 2005 to create managed DLLs such as .NET assemblies and to create unmanaged DLLs such as Win32 DLLs and COM DLLs.

Your Visual Basic .NET application can call a function in a Visual C++ .NET or Visual C++ 2005 managed DLL or in a Visual C++ .NET or Visual C++ 2005 unmanaged DLL as if the function were written in Visual Basic .NET or in Visual Basic 2005. This article discusses the methods of passing an array to managed DLLs and to unmanaged DLLs. This article also provides code samples for each scenario that is discussed. The sample code that is included in this article searches for a specified number in the integer array that is passed to the Visual C++ .NET or Visual C++ 2005 function and then returns the position of the element in the array.

back to the top

Requirements
This article assumes that you are familiar with the following topics:
 * Microsoft Visual Basic .NET or Microsoft Visual Basic 2005 programming
 * Microsoft Visual C++ .NET or Microsoft Visual C++2005 programming
 * Microsoft Active Template Library (ATL) programming

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
 * Microsoft Visual Studio .NET or Microsoft Visual Studio 2005
 * Microsoft Visual Basic .NET or Microsoft Visual Basic 2005
 * Microsoft Visual C++ .NET or Microsoft Visual C++ 2005
 * Microsoft .NET Framework

back to the top

Create a Visual Basic .NET or Visual Basic 2005 application

 * 1) Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
 * 2) On the File menu, point to New, and then click Project. The New Project dialog box appears.
 * 3) Under Project Types, click Visual Basic Projects.

Note In Visual Studio 2005, click Visual Basic under Project Types.
 * 1) Under Templates, click Console Application.
 * 2) In the Name box, type MyVBApp, and then click OK.

back to the top

Pass an array to a function in a .NET Framework assembly
You can create a .NET Framework assembly in Visual C++ .NET by using the Managed C++ Class Library template in Microsoft Visual C++ .NET 2002 or by using the Class Library (.NET) template in Microsoft Visual C++ .NET 2003. You can load this .NET Framework assembly in your Visual Basic .NET or Visual Basic 2005 application by adding a reference to the assembly. After you add a reference to the assembly, you can use all the functions and all the classes that are defined in the assembly as if they were defined in the Visual Basic .NET or Visual Basic 2005 application.

back to the top

Create an assembly by using Visual C++ .NET or Visual C++ 2005

 * 1) Start Visual Studio .NET or Visual Studio 2005.
 * 2) On the File menu, point to New, and then click Project. The New Project dialog box appears.
 * 3) Under Project Types, click Visual C++ Projects.

Note In Visual Studio 2005, click Visual C++ under Project Types.
 * 1) Do one of the following, depending on the version of Visual C++ .NET or Visual C++ 2005 that you are using:
 * 2) * If you are using Microsoft Visual C++ .NET 2003, click Class Library (.NET) under Templates.
 * 3) * If you are using Microsoft Visual C++ .NET 2002, click Managed C++ Class Library under Templates.
 * 4) * If you are using Microsoft Visual C++ 2005, click Class Library under Templates.
 * 5) In the Name box, type MyCDll, and then click OK.

back to the top

Write a Visual C++ .NET function that expects an array
To write a function that receives an array in the .NET Framework assembly, follow these steps:  In Solution Explorer, double-click MyCDll.h under Header Files.  Add the following code to the Class1 class: /*======================================================== SearchNum_Assembly is a function that searches for a number in the array. If the specified number is present, the function returns the position of the element in the array.

=
=============================================*/ public: int SearchNum_Assembly(int numArr __gc[], int searchnum) {  int i,value=0; for (i=0;iCount;i++) {         if (searchnum==numArr[i]) {         value=i+1; break; }  }   //Return the position of the number in the array. return value; }  On the Build menu, click Build MyCDll to create the MyCDll.dll file. By default, MyCDll.dll file is created in the Debug folder that is located in your project folder. On the File menu, click Exit to close the MyCDll project.

back to the top

Call the function in the .NET Framework assembly
To call the function in the .NET Framework assembly from the Visual Basic .NET or Visual Basic 2005 application, follow these steps:  Switch to the Visual Basic .NET or Visual Basic 2005 project.</li> In Solution Explorer, right-click MyVBApp, and then click Add Reference. The Add Reference dialog box appears.</li> In the Add Reference dialog box, click the .NET tab, and then click Browse. The Select Component dialog box appears.</li> In the Select Component dialog box, locate the MyCDll folder on your computer. Double-click the MyCDll folder, and then double-click the Debug folder.</li> In the Select Component dialog box, click MyCDll.dll, and then click Open.</li> In the Add Reference dialog box, click OK.</li>  Add the following code to the Main procedure: 'Declare an integer array, and then initialize the array. Dim nums As Integer = {1, 2, 3, 4, 5, 6} Dim result, searchNum As Integer searchNum = InputBox(&quot;Enter the number to be searched:&quot;) Dim obj As New MyCDll.Class1 'Pass the elements of the array to the SearchNum_Assembly function 'in the MyCDll assembly. result = obj.SearchNum_Assembly(nums, searchNum) Console.WriteLine(&quot;RESULT WHEN THE ARRAY IS PASSED TO A FUNCTION IN Visual C++ .NET ASSEMBLY:&quot;) If result <> 0 Then Console.WriteLine(&quot;The number is present and the position of the number is:&quot; & result) Else Console.WriteLine(&quot;The number is not present.&quot;) End If Console.ReadLine </li></ol>

back to the top

Pass an array to a function in a Win32 DLL
A Win32 DLL is a binary file that you can create by using either Visual C++ .NET or Microsoft Visual C++. In Visual C++ .NET or Visual C++ 2005, you can create a Win32 DLL by using the Win32 Project template. The Win32 DLL is a shared library of functions. You can use these functions in multiple applications.

To use these functions in other applications, such as in a Visual Basic .NET or Visual Basic 2005 application, you must export the functions from the Win32 DLL. To export the functions from the Win32 DLL, use the __declspec keyword together with the dllexport attribute.

For example, the following sample code is the prototype of the Visual C++ .NET or Visual C++ 2005 function that receives a pointer to the array and returns the position of the element in the array: int __declspec (dllexport) __stdcall SearchNum_Win32( int *numArr, int count, int searchnum); In this example, the first parameter is a pointer to the array, the second parameter provides the number of elements in the array, and the third parameter provides the number to be searched in the array.

To call the function in the Win32 DLL from a Visual Basic .NET or Visual Basic 2005 application, you have to use the Declare statement or the dllimport attribute that enables the managed code to call C-style functions in the native DLLs. In Visual Basic .NET or Visual Basic 2005, the function is declared in the following way: Private Declare Function SearchNum_Win32 Lib &quot;<Full Path of DLL>&quot; _ (ByRef nums As Integer, ByVal count As Integer, ByVal searchNum As Integer) As Integer Note In this example, <Full Path of DLL> is a placeholder for the full path of the Win32 DLL that you are trying to access.

back to the top

Create a Win32 DLL by using Visual C++ .NET

 * 1) Start Visual Studio .NET or Visual Studio 2005.
 * 2) On the File menu, point to New, and then click Project. The New Project dialog box appears.
 * 3) Under the Project Types section, click Visual C++ Projects.

Note In Visual Studio 2005, click Visual C++ under Project Types.
 * 1) Under the Templates section, click Win32 Project.
 * 2) In the Name box, type MyWinDll.
 * 3) In the Location box, type C:\WinDll, and then click OK. The Win32 Application Wizard - MyWinDll wizard starts.
 * 4) On the Welcome to the Win32 Application Wizard page, click Application Settings.
 * 5) On the Application Settings page, click DLL, and then click Finish.

back to the top

Write a Visual C++ .NET or Visual C++ 2005 function that expects a pointer to an array
To call a function from a Visual Basic .NET application, you must export the function from the Win32 DLL. To export the function, add the __declspec(dllexport) keyword to the function, and then add the function to the module definition file. To export a function that expects a pointer to an integer array, follow these steps:  In Solution Explorer, right-click Header Files, point to Add, and then click Add New Item. The Add New Item - MyWinDll dialog box appears.</li> Under Templates, click Header File (.h).</li> In the Name box, type MyWinDll, and then click Open. The MyWinDll.h file opens in code view.</li>  Add the following code to the MyWinDll.h file: int __declspec (dllexport) __stdcall SearchNum_Win32(int In Solution Explorer, right-click MyWinDll.cpp, and then click Open. The MyWinDll.cpp file opens in code view.</li>  Add the following code at the end of the MyWinDll.cpp file:
 * 1) include <windows.h>
 * numArr, int count, int searchnum); </li>
 * 1) include &quot;MyWinDll.h&quot;

/*========================================================  SearchNum_Win32 is a function that searches for a specified number in the array that is passed as a pointer. If the specified number is present, the function returns the position of the element in the array. ==========================================================*/

int __declspec (dllexport) __stdcall SearchNum_Win32( int *numArr, // The array's pointer int count, // The number of elements in the array int searchnum)// The number to be searched {

int i,value=0; for (i=0;i<count;i++) {         if (searchnum==numArr[i]) {         value=i+1; break; }  }   //Return the position of the number in the array. return value; } </li> In Solution Explorer, right-click Source Files, point to Add, and then click Add New Item. The Add New Item - MyWinDll dialog box appears.</li> Do one of the following, depending on the version of Visual C++ .NET that you are using: <ul> <li>If you are using Visual C++ .NET 2003, click Module-Definition File (.def) under Templates.</li> <li>If you are using Visual C++ .NET 2002, click DEF File (.def) under Templates.</li></ul> </li> <li>In the Name box, type MyWinDll, and then click Open. The MyWinDll.def file opens in code view.</li> <li> Add the following code at the end of the MyWinDll.def file: EXPORTS SearchNum_Win32 </li> <li>On the Build menu, click Build MyWinDll.</li> <li>On the File menu, click Exit to close the MyWinDll project.</li></ol>

back to the top

Call the function in the Win32 DLL
To call the function in the Win32 DLL, you must declare a reference to the function in the Visual Basic .NET or Visual Basic 2005 application. To do this, follow these steps: <ol> <li>Switch to the Visual Basic .NET or Visual Basic 2005 project.</li> <li> Add the following code before the Main procedure in the Module1 module: Private Declare Function SearchNum_Win32 Lib &quot;C:\WinDll\MyWinDll\Debug\MyWinDll.dll&quot; _ (ByRef nums As Integer, ByVal count As Integer, ByVal searchNum As Integer) As Integer </li> <li> Locate the following code: End Sub </li> <li> Add the following code to the Main procedure. Add this code before the code that you located in step 3: 'Pass the first element of the integer array to the SearchNum_Win32 function 'in the MyWinDll Win32 DLL. Dim presult As Integer presult = SearchNum_Win32(nums(0), UBound(nums) + 1, searchNum) Console.WriteLine(&quot;RESULT WHEN THE FIRST ELEMENT OF THE ARRAY IS PASSED TO A FUNCTION IN WIN32 DLL:&quot;) If presult <> 0 Then Console.WriteLine(&quot;The number is present and the position of the number is:&quot; & presult) Else Console.WriteLine(&quot;The number is not present.&quot;) End If Console.ReadLine </li></ol>

back to the top

Pass an array to a function in a COM DLL
You can create a COM DLL in Visual C++ .NET by using the ATL Project template. When you use the ATL Project template to create a DLL, a type library is created. Function calls between Visual Basic .NET and the COM DLL use this type library. When you use type libraries, you do not have to declare references to the functions by using a dllimport attribute or a Declare statement in your code. Visual Basic .NET obtains all the information that it requires from the type libraries. To use the functions that are defined in the COM DLL, you must create a reference to the COM DLL from your Visual Basic .NET application.

back to the top

Create a COM DLL by using Visual C++ .NET

 * 1) Start Visual Studio .NET or Viusal Studio 2005.
 * 2) On the File menu, point to New, and then click Project. The New Project dialog box appears.
 * 3) Under Project Types, click Visual C++ Projects.

Note In Visual Studio 2005, click Visual C++ under Project Types.
 * 1) Under Templates, click ATL Project.
 * 2) In the Name box, type MyAtlDll, and then click OK. The ATL Project Wizard - MyAtlDll starts.
 * 3) On the Welcome to the ATL Project Wizard page, click Application Settings.
 * 4) On the Application Settings page, click Dynamic-link library (DLL), click to clear the Attributed check box, and then click Finish.

back to the top

Write a Visual C++ .NET or Visual C++ 2005 function that expects a SAFEARRAY
A SAFEARRAY is a structure that provides important information about an array, including a pointer to the actual elements of the array. The definition for a SAFEARRAY depends on the operating system that you are using. In Win32, the following is the SAFEARRAY structure after all type definitions (typedefs) and all conditional directives that are included in its declaration have been replaced: struct SAFEARRAY {     WORD cDims; // The number of dimensions WORD fFeatures; // The bitfield that indicates the attributes of a specific // array DWORD cbElements; // The size of an element of the array DWORD cLocks; // The lock counter Void * pvData; // The pointer to the array's elements (use only if the value                    // of cLocks is greater than 0) SAFEARRAYBOUND rgsabound[1]; // The structure that contains information for // each dimension }; To write a Visual C++ .NET function that uses the SAFEARRAY structure, follow these steps: <ol> <li>In Solution Explorer, right-click Source Files, point to Add, and then click Add Class. The Add Class - MyAtlDll dialog box appears.</li> <li>Under Templates, double-click ATL Simple Object. The ATL Simple Object Wizard - MyAtlDll starts.</li> <li>On the Welcome to the ATL Simple Object Wizard page, type MyClass in the Short name box, and then click Options.</li> <li>On the Options page, verify that: <ul> <li>Threading model is set to Apartment.</li> <li>Aggregation is set to Yes.</li> <li>Interface is set to Dual.</li></ul>

Click Finish.</li> <li>On the View menu, click Class View.</li> <li>In class view, expand MyAtlDll, right-click IMyClass, point to Add, and then click Add Method. The Add Method Wizard - MyAtlDll starts.</li> <li>On the Welcome to the Add Method Wizard page, type SearchNum_Com in the Method name box.</li> <li>In the Parameter type box, type SAFEARRAY* .</li> <li>In the Parameter name box, type numArr, and then click Add.</li> <li>Repeat steps 8 and 9 for the following values: </li> <li>On the Welcome to the Add Method Wizard page, click Finish.</li> <li>On the View menu, click Solution Explorer.</li> <li>In Solution Explorer, right-click MyAtlDll.idl, and then click Open. The MyAtlDll.idl file opens in code view.</li> <li> Locate the following code: [id(1), helpstring(&quot;method SearchNum_Com&quot;)] HRESULT SearchNum_Com(SAFEARRAY* numArr, int searchnum, int* result); </li> <li> Replace the code that you located in step 14 with the following code: [id(1), helpstring(&quot;method SearchNum_Com&quot;)] HRESULT SearchNum_Com(SAFEARRAY(int) numArr, int searchnum, int* result); </li> <li>In Solution Explorer, right-click MyClass.cpp, and then click Open. The MyClass.cpp file opens in code view.</li> <li> Replace the existing code in the SearchNum_Com function with the following code: /*======================================================== SearchNum_Com is a function that searches for a specified number in the array that is passed from a Visual Basic .NET application. The variable &quot;result&quot; is passed by reference. This variable holds the results of the search. If the specified number is present, the function updates the variable &quot;result&quot; to hold the position of the number in the array.

=
=============================================*/ int i,arrSize; int* arrData; //Get the number of elements in the array. arrSize=numArr->cbElements; //Get the elements in the array. arrData=(int*)(numArr)->pvData; for (i=0;i<arrSize;i++) {      if (searchnum==arrData[i]) {         *result=i+1; break; } } return S_OK; </li> <li>On the Build menu, click Build MyAtlDll.</li> <li>On the File menu, click Exit to close the MyAtlDll project.</li></ol>
 * result=0;

back to the top

Call the function in the COM DLL
To call the Visual C++ .NET function in the COM DLL, you must create a reference to the COM DLL in your Visual Basic .NET console application. To do this, follow these steps: <ol> <li>Switch to the Visual Basic .NET or Visual Basic 2005 project.</li> <li>In Solution Explorer, right-click MyVBApp, and then click Add Reference. The Add Reference dialog box appears.</li> <li>In the Add Reference dialog box, click the COM tab, and then click Browse. The Select Component dialog box appears.</li> <li>In the Select Component dialog box, locate the MyAtlDll folder on your computer. Double-click MyAtlDll, and then double-click Debug.</li> <li>In the Select Component dialog box, click MyAtlDll.dll, and then click Open.</li> <li>In the Add Reference dialog box, click OK.</li> <li> Locate the following code: End Sub </li> <li> Add the following code to the Main procedure. Add this code before the code that you located in step 7: Dim Atlobj As New MyAtlDllLib.MyClassClass 'Pass the integer array to the SearchNum_Com function in 'the COM DLL. Dim cres As Integer Atlobj.SearchNum_Com(nums, searchnum, cres) Console.WriteLine(&quot;RESULT WHEN THE ARRAY IS PASSED TO A FUNCTION IN THE COM DLL:&quot;) If cres <> 0 Then Console.WriteLine(&quot;The number is present and the position of the number is:&quot; & cres) Else Console.WriteLine(&quot;The number is not present.&quot;) End If Console.ReadLine </li></ol>

back to the top

Verify that your project works
To verify that your Visual Basic .NET project works, follow these steps:
 * 1) On the Build menu, click Build Solution.
 * 2) On the Debug menu, click Start.

back to the top

<div class="references_section">