Click here to Skip to main content
Click here to Skip to main content

Beginner's Tutorial: Calling Visual Basic ActiveX DLLs from Visual C++

By , 18 Nov 1999
 
  • Download source - 8 Kb
  • This tutorial is based off of the MSDN Article #ID: Q194873. But, for a beginner, following these MSDN articles can be intimidating to say the least. One of the most often asked questions I see as a Visual C++ and Visual Basic programmer is how to call a VB DLL from VC++. Well, I am hoping to show you exactly that today. I am not going to go over the basic details of COM as this would take too long, so I am assuming you have an understanding of VB, VC++ and a little COM knowledge. It's not too hard to learn; just takes a little time. So let's get started.

    The first thing you need to do is fire up Visual Basic 6 (VB 5 should work as well). With VB running, create a new "ActiveX DLL" project. Rename the project to "vbTestCOM" and the class to "clsTestClass". You can do this by clicking in the VB Project Explorer Window on the Project1 item (Step 1), then clicking in the Properties window and selecting the name property (Step 2). Do the same for the Class. Click on the class (Step 3), then the name property and enter the name mentioned above (Step 4). Your project so far should look like the folowing right hand side picture:

    Naming the Project

    Ok, now we are ready to add some code to the VB Class. Click on the "Tools" menu, then select the "Add Procedure" menu item. The Add Procedure window will open up. In this window we need to add some information. First (Step 1) make sure the type is set to Function. Second (Step 2) enter a Function name called "CountStringLength". Finally hit the Ok button and VB will generate the new function in the class.

    Add Procedure Window

    You should have an empty function with which to work. The first thing we will do is specify a return type and an input parameter. Edit your code to look like this:

    Public Function CountStringLength(ByVal strValue As String) As Long
    
    End Function
    

    What are we doing here? We are taking one parameter, as a String type in this case, then returning the length through the return type, which is a Long. We specify the input parameter as ByVal, meaning VB will make a copy of this variable and use the copy in the function, rather than the default ByRef, which passes the variable by reference. This way we can be sure that we do not modify the string by accident that was passed to us by the calling program. Let's add the code now.

    Public Function CountStringLength(ByVal strValue As String) As Long
    	If strValue = vbNullString Then
            	CountStringLength = 0
        	Else
            	CountStringLength = Len(strValue)
        	End If
    End Function
    

    In the first line of code we are checking to see if the calling program passed us an empty, or NULL, string. If so we return 0 as the length. If the user did pass something other than an empty string, then we count it's length and return the length back to the calling program.

    Now would be a good time to save your project. Accept the default names and put it in a safe directory. We need to compile this project now. Go to the File menu and select the "Make vbCOMTest.dll..." menu item.

    Compiling the ActiveX DLL

    The compiler will produce a file called surprisingly enough: vbCOMTest.dll. The compiler will also do us the favor of entering this new DLL into the system registry. We have finished the VB side of this project, so let's start the VC++ side of it. Fire up a copy of VC++, then select from the menu, "New Project". The New Project window should appear. Select a "Win32 Console Application" (Step 1), then give it a name of "TestVBCOM" (Step 2). Finally, enter a directory you want to build this project in (Step 3 - your directory will vary from what I have entered).

    VC++ New Project Window

    Click on the "OK" button and the "Win32 Console Application - Step 1 of 1" window will appear. Leave everything on this page as the default, and click the "Finish" button. One final window will appear after this titled "New Project Information". Simply click the "Ok" button here. You should now have an empty Win32 Console project. Press the "Ctrl" and hit the "N" key. Another window titled "New" will appear. Select the "C++ Source File" (Step 1), then enter the new name for this file called, "TestVBCOM.cpp" (Step 2 - make sure the Add to Project checkbox is checked and the correct project name is in the drop down combo box), then click the "Ok" button to finish.

    Adding a New C++ Source File

    Now we are going to get fancy! You need to go to your Start Menu in Windows and navigate to the "Visual Studio 6" menu and go into the "Microsoft Visual Studio 6.0 Tools" sub-menu. In here you will see an icon with the name "OLE View". Click on it.

    Starting OLE View

    The OLE View tool will open up. You will see a window similar to this one:

    Starting OLE View

    Collapse all the trees, if they are not already. This will make it easier to navigate to where we want to go. Highlight the "Type Libraries" (Step 1) and expand it. You should see a fairly massive listing. We need to locate our VB DLL. Now, remember what we named the project? Right, we need to look for vbTestCOM. Scroll down until you find this. Once you have found it, double click on it. A new window should appear - the "ITypeLib Viewer" window. We are only interested in the IDL (Interface Definition Language) code on the right side of the window. Select the entire IDL text and hit the "Ctrl" and "C" buttons to copy it to the clipboard.

    Copying the IDL file

    You can close this window and the OLE View window now as we are done with the tool. We need to add the contents of the IDL file into our VC++ project folder. Go to the folder you told VC++ to create your project in and create a new text file there (If you are in Windows Explorer, you can right click in the directory and select "New" then scroll over following the arrow and select "Text Document"). Rename the text document to "vbCOMTEST.idl". Then double click on the new IDL file (VC++ should open it if you named it correctly with an IDL extension). Now paste the code in the file by pressing the "Ctrl" and "V" keys. The IDL text should be pasted into the file. So far, so good. Now, this IDL file is not going to do us much good until we compile it. That way, VC++ can use the files it generates to talk to the VB DLL. Let's do that now. Open a DOS window and navigate to the directory you created your VC++ project in. Once in that directory, at the prompt you need to type the following to invoke the MIDL compiler:

    E:\VCSource\TestVBCOM\TestVBCOM\midl vbTestCOM.idl /h vbTestCOM.h
    

    Hit the "Enter" key and let MIDL do its magic. You should see results similar to the following:

    Compiling the IDL file with the MIDL compiler

    Close the DOS window and head back into VC++. We need to add the newly generated vbTestCOM.h and vbTestCOM_i.c files to the project. You can do this by going to the "Project" menu, then selecting the "Add to Project" item, and scrolling over to the "Files" menu item and clicking on it. A window titled, "Insert Files into Project" will open. Select the two files highlighted in the next picture, then select the "Ok" button.

    Adding the files generated by MIDL

    These two files were generated by MIDL for us, and VC++ needs them in order to talk to the VB DLL (actually VC++ does not need the "vbCOMTest_i.c" file in the project, but it is handy have in the project to review). We are going to add the following code to the "TestVBCOM.cpp" file now, so navigate to that file in VC++ using the "Workspace" window. Open the file by double clicking it and VC++ will display the empty file for editing.

    Updated Workspace Window

    Now add the following code to the "TestVBCOM.cpp" file:

    #include <iostream.h>
    #include <comdef.h>
    #include "vbTestCOM.h"
    
    void main()
    {
       	// Declare an HRESULT and a pointer to the clsVBTestClass interface
       	HRESULT		hr;
    	_clsVBTestClass	*IVBTestClass = NULL;
    	
    	// Now we will intilize COM
    	hr = CoInitialize(0);
    
    	// Use the SUCCEEDED macro and see if we can get a pointer 
    	// to the interface
    	if(SUCCEEDED(hr))
    	{
    		hr = CoCreateInstance( CLSID_clsVBTestClass,
    					NULL,
    					CLSCTX_INPROC_SERVER,
    					IID__clsVBTestClass, 
    					(void**) &IVBTestClass);
    		
    		// If we succeeded then call the CountStringLength method, 
    		// if it failed then display an appropriate message to the user.
    		if(SUCCEEDED(hr))
    		{
    			long		ReturnValue;
    			_bstr_t		bstrValue("Hello World");
    			
    			// We can test this HR as well if we wanted to
    			hr = IVBTestClass->CountStringLength(bstrValue,
    							&ReturnValue);
    
    			cout << "The string is: " << ReturnValue << " characters in
    							length." << endl;
    			// We can test this HR as well if we wanted to
    			hr = IVBTestClass->Release();
    		}
    		else
    		{
    			// Something went wrong
    			cout << "CoCreateInstance Failed." << endl;
    		}
    	}
    	// Uninitialize COM
    	CoUninitialize();
    }
    

    If all the code is entered in correctly, then press the "F7" key to compile this project. Once the project has compiled cleanly, then press the "Ctrl" and the "F5" keys to run it. In the C++ code, we include the MIDL created "vbTestCOM.h" file, the "Comdef.h" file for the _bstr_t class support and the "iostream.h" file for the "cout" support. The rest of the comments should speak for themselves as to what's occurring. This simple tutorial shows how well a person can integrate VB and VC++ apps together using COM. Not too tough actually.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    C. Lung
    United States United States
    Member
    No Biography provided

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    QuestionThe good old VC 6 (RIP)memberKarstenK18 Dec '06 - 21:28 
    is very old, but I liked it.   But I think with VS2005 and the .net technology there are easier ways. That could be interesting!   Greetings from Germany
    QuestionA Better Way?memberTom Moore5 Aug '06 - 0:53 
    Instead of using a pointer by using _clsVBTestClass *IVBTestClass = NULL;   would it be better to use a CComPtr instead or a CComQIPtr maybe? E.g.   HRESULT hr; CComPtr IVBTestClass;   or   HRESULT hr; CComQIPtr IVBTestClass;   ...
    QuestionHow to return a string-variable ?memberHansnet8322 Jun '06 - 10:51 
    Hello, Does any body know how to return a string-variable back to the C++ program; the article only shows it with a long-variable. I followed the same steps with an extra VB-function that returns a string, but I can't get the VC++ program to work.   VC++ :   _bstr_t RetStrValue;...
    Generalvc++ errormembersriadaptime20 Feb '06 - 23:53 
    hi   pls clear my doubt the error are follow by the time of generating build Dll in vc++ this for using vb dll in vc++   fatal error C1010: unexpected end of file while looking for precompiled header directive   help me to know the result   Thanks   sridhar
    GeneralRe: vc++ errormembervanip23 Mar '06 - 19:01 
    i too got the same error. Can anybody explain this????????????????
    AnswerRe: vc++ errormembervanip26 Mar '06 - 15:50 
    I got solved by selecting,.... Project->Settings->c/c++->category->Precomipled headers->Not using precompiled headers. Thismay be useful for others. Thanks,
    General'vbTestCOM.h': No such file or directorymemberShanjaq30 Nov '05 - 7:44 
    For some reason if I include "stdafx.h" in my project, when I move the inclusion for "vbTestCOM.h" to *before* stdafx it is completely ignored, and if I include it *after* stdafx I get this error saying it doesn't even exist! What is going on here?   ...
    Generaldevice is not readysussAnonymous29 Jun '05 - 22:39 
    hi, I tried to do everything you explained above but when I tried to invoke the midl compiler E:\VCSource\TestVBCOM\TestVBCOM\midl vbTestCOM.idl /h vbTestCOM.h it gave the following error device is not ready.. do you know what might cause this? thanks... gül
    GeneralErrors while VC Prj compilingmemberpeterfarge21 Feb '05 - 22:59 
    Hello,   in this Article are a lot of errors:   :\Temp\TestVBCOM\TestVBCOM.cpp(9) : error C2065: '_clsVBTestClass' : undeclared identifier C:\Temp\TestVBCOM\TestVBCOM.cpp(9) : error C2065: 'IVBTestClass' : undeclared identifier C:\Temp\TestVBCOM\TestVBCOM.cpp(9) : warning C4552:...
    GeneralMIDL compiler errorsussrojnet9 May '04 - 9:45 
    i followed all the steps but i couldnt compile .idl file.. when i type midl it says bad command or file name.   Do i have to install MIDL compiler ?
    GeneralRe: MIDL compiler errorsussIsmag11 Jun '04 - 20:33 
    I get compiling copying the .idl file in VC/Bin folder so:   C:\Program Files\Microsoft Visual Studio\VC98\Bin   and then executing midl but i'm having problems also.
    GeneralRe: MIDL compiler errormemberJanice Lee17 Jun '04 - 17:44 
    Yes, you need to reinstall Platform SDK. This might be caused by incomplete installation!   Janice Lee
    GeneralRe: MIDL compiler errormemberStefanBrunn21 Dec '04 - 2:42 
    MIDL compiler is normally installed with visual studio. You must call vcvars32.bat (with full path) in your command window to set the correct environment before calling midl. File vcvars32.bat is optionally generated during installation of visual studio.
    QuestionRe: MIDL compiler errormemberMember 322003813 Aug '08 - 19:51 
    Checked the PATH, INCLUDE, LIB env. Variables Reinstalled Visual Studio 6.0 Tried on both Visual Studio Professional , Enterprise In command prompt, ran midl with & without executing VCVARS32.bat NO EFFECT   Still the Same ERROR :: MIDL1003 persists   // OUTPUT Window : Processing...
    Generalyou can just using the &quot;#import&quot; directive to import a typelib or a exe/dll module with typelib resourcememberchen3fengx@hotmail.com26 Apr '04 - 15:42 
    eg: #import "test.dll" no_namespace I's a better way to do that.
    GeneralCoCreateInstance failedmembereric107614 Oct '03 - 3:27 
    My task is to call a VB activeX DLL function from a C++ DLL. After following the article by C. Lung on "Calling Visual Basic ActiveX DLLs from Visual C++", I am receiving the output "CoCreateInstance failed" with a return code of -2147467262.   Does anybody have any ideas why this...
    GeneralRe: CoCreateInstance failedmemberShanjaq30 Nov '05 - 8:08 
    I get this same error.. Author please explain why this could happen!
    GeneralRe: CoCreateInstance failedmemberjtholt6 Mar '07 - 12:23 
    I got the same error using VC6 SP5.
    GeneralRe: CoCreateInstance failedmemberwilsonsuryajaya8 Dec '11 - 14:38 
    Try registering the dll to registry using regsvr32
    GeneralReturning ADO Recordset from VB DLLmembertakrimcode26 Aug '03 - 0:26 
    Hi All   I am trying to return Recordset from my VB Dll Function . I am using ADO 2.5 library while compliling vbCOMTest.idl it is giving error in this statement   library vbTestCOM { // TLib : // TLib : Microsoft ActiveX Data Objects 2.5 Library :...
    GeneralCalling Visual Basic ActiveX Control from Visual C++memberhungit98013 Aug '03 - 20:54 
    I have test this example and it works very good but I can't call an ActveX Control ( myctl.ocx written by Visual Basic) from Visual C++ ( Win32 Console App). Please help me do Thanhyou very much !   (When I do similar with an ActiveX Control(myctl.oxc written by Visual Basic) an Error...
    GeneralRe: Calling Visual Basic ActiveX Control from Visual C++memberDonal Gleeson26 May '05 - 22:58 
    Hi, did you solve the problem of the exception? I have a similar problem with the second version of a Visual Basic ActiveX DLL received from a supplier. The first version of the DLL works ok. Thanks
    QuestionHow calling VIsual Basic ActiveX Control from Visual C++memberhungit98013 Aug '03 - 18:37 
    I have test this example and it works very good but I can't call an ActveX Control ( myctl.ocx written by Visual Basic) from Visual C++ ( Win32 Console App). Please help me do Thanhyou very much !   (When I do similar with an ActiveX Control(myctl.oxc written by Visual Basic) an Error...
    QuestionHow do calling Visual Basic ActiveX Control (myctrl.ocx) from Visual C++ ?memberhungit98013 Aug '03 - 17:08 
    I have been test this example and it works very good . But I can't calling an ActiveX Control ( myctrl.ocx) . please help me calling with an ActiveX Control Thanhyou vey much !
    GeneralActive X DLL called by VC++ appmemberYank14 Apr '03 - 3:00 
    Can somebody provide me with an example of how to pass arrays from a VB created ActiveX DLL to a VC++ app using the SAFEARRAY

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web02 | 2.6.130516.1 | Last Updated 19 Nov 1999
    Article Copyright 1999 by C. Lung
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid