Click here to Skip to main content
Email Password   helpLost your password?
  • 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.

    You must Sign In to use this message board.
     
     
    Per page   
     FirstPrevNext
    GeneralThanks for the articles
    laurenperram
    13:09 24 Aug '09  
    Thanks for the great articles it really helps someone new like me.
    QuestionCan we run the above vc++ application by replacing the existing dll with Updated dll (add a new public function) without builing the vc++ application
    rameshbabu_peddapalli
    20:19 15 Oct '08  
    I have done the "Calling a VB ActiveX DLL from a MFC Client" exercise successfully.
    I have a requirement that, adding a new Public function (eg fncDLL2())in VB DLL and make dll.
    Now without building the vc++ application replace the dll in the current folder and run the exe. When i did the same i am getting "Creation Failed" error.


    Please try to give the solution to my problem
    QuestionError generating type library
    rameshbabu_peddapalli
    22:23 6 Oct '08  
    I have created an activeX DLL. It contains a class as shown below
    -----------------------------------------
    Option Explicit

    Public Type T
    i As Integer
    d As Double
    l As Long
    s As String
    End Type

    Public Function TypeValue() As Long

    Dim a As T
    a.i = 10

    TypeValue = a.i

    End Function
    ---------------------------------------------------
    I can able to make dll but, when i try to compile .idl file using MIDL it's giving an error the error message is as follows

    "midl\oleaut32.dll : warning MIDL2368 : error generating type library, ignored : Could not set UUID :
    tagT"
    GeneralMIDL1003 + C1083 Error Persists
    Member 3220038
    11:25 14 Aug '08  
    Checked the PATH, INCLUDE, LIB env. Variables
    Tried on both Visual Studio Professional , Enterprise, Visual Studio.net2003 on a fresh installation after removing previous installations & deleting all LIB, INCLUDE, PATH , registry entries (using regedit), & did fresh installations.
    In command prompt, ran midl with & without executing VCVARS32.bat
    Copied the file vbTestCOM.idl in all LIB , INCLUDE, bin Dir
    checked with TestvbCOM.idl, vbTestCOM.idl
    still...NO EFFECT

    Still the Same ERROR :: MIDL1003 persists

    // OUTPUT same by both IDE & command prompt:
    Processing .\vbTestCOM.idl
    %CL%
    fatal error C1083: Cannot open source file: '%CL%': No such file or directory
    vbTestCOM.idl
    midl : command line error MIDL1003 : error returned by the C preprocessor (2)

    PLEASE HELP
    GeneralPossibilities of calling functions in existing dll(MFC AppWizard dll) from VB activex dll
    mdhanif
    21:09 5 Mar '08  
    I have a problem when i access the VB activeX DLL fuction which inturn call the regular DLL fuction from my VB application.I am using the late binding to access the ActiveX DLL from my VB application . Can you help me regarding this. You can suggest any other idea to resolve.

    Thank you,
    Regards,

    KSMH
    QuestionAnybody know to dynamically link the vb activex dll with vc
    JothiMurugeswaran
    2:04 16 Nov '07  
    Anybody know to dynamically link the vb activex dll with vc?

    Jothi Murugeswaran.S

    GeneralThank you!
    MohammadAmiry
    9:48 28 Apr '07  
    You Really helped me with your article!!
    THANKS Rose Laugh
    QuestionThe good old VC 6 (RIP)
    KarstenK
    22:28 18 Dec '06  
    is very old, but I liked it. Blush

    But I think with VS2005 and the .net technology there are easier ways. That could be interesting!
    Roll eyes

    Greetings from Germany

    QuestionA Better Way?
    Tom Moore
    1:53 5 Aug '06  
    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<_clsVBTestClass> IVBTestClass;

    or



    HRESULT hr;
    CComQIPtr<_clsVBTestClass> IVBTestClass;


    Just a thought

    Tom
    GeneralHow to return a string-variable ?
    Hansnet83
    11:51 22 Jun '06  
    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;

    hr = IVBTestClass->DoString(bstrValue, &RetStrValue);

    cout << "The returnstring is: " << RetStrValue << endl;

    The C++ compiler says :
    error C2664: 'DoString' : cannot convert parameter 2 from 'class _bstr_t *' to 'unsigned short ** '

    VB-function :
    Public Function DoString(ByVal strValue As String) As String
    If strValue = vbNullString Then
    DoString = ""
    Else
    DoString = "RETURN" & strValue * "RETURNNNN"
    End If
    End Function
    Generalvc++ error
    sriadaptime
    0:53 21 Feb '06  
    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++ error
    vanip
    20:01 23 Mar '06  
    i too got the same error.
    Can anybody explain this????????????????
    AnswerRe: vc++ error
    vanip
    16:50 26 Mar '06  
    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 directory
    Shanjaq
    8:44 30 Nov '05  
    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?


    D:\backup\projects\Server\IOCP\srv\worker.cpp(11) : fatal error C1083: Cannot open include file: 'vbTestCOM.h': No such file or directory
    Generaldevice is not ready
    Anonymous
    23:39 29 Jun '05  
    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 compiling
    peterfarge
    23:59 21 Feb '05  
    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: '*' : operator has no effect; expected operator with side-effect
    C:\Temp\TestVBCOM\TestVBCOM.cpp(18) : error C2065: 'CLSID_clsVBTestClass' : undeclared identifier
    C:\Temp\TestVBCOM\TestVBCOM.cpp(21) : error C2065: 'IID__clsVBTestClass' : undeclared identifier
    C:\Temp\TestVBCOM\TestVBCOM.cpp(32) : error C2227: left of '->CountStringLength' must point to class/struct/union
    C:\Temp\TestVBCOM\TestVBCOM.cpp(35) : error C2001: newline in constant
    C:\Temp\TestVBCOM\TestVBCOM.cpp(36) : error C2146: syntax error : missing ';' before identifier 'length'
    C:\Temp\TestVBCOM\TestVBCOM.cpp(36) : error C2065: 'length' : undeclared identifier
    C:\Temp\TestVBCOM\TestVBCOM.cpp(36) : error C2001: newline in constant
    C:\Temp\TestVBCOM\TestVBCOM.cpp(36) : error C2059: syntax error : 'string'
    C:\Temp\TestVBCOM\TestVBCOM.cpp(43) : error C2228: left of '.cout' must have class/struct/union type
    C:\Temp\TestVBCOM\TestVBCOM.cpp(43) : error C2297: '<<' : illegal, right operand has type 'char [25]'
    Error executing cl.exe.

    TestVBCOM.exe - 12 error(s), 1 warning(s)


    Sometimes you write "_clsVBTestClass", on other locations "_clsTestClass", or the projectname is sometimes "TestVBCom", sometimes "vbTestCOM". The Sourcecode in the article and in the zip are also not equal.

    I can fix the errors for myself. But it is annoyed to fix so much errors in a so little project. --> Review this articel.



    Peter
    GeneralMIDL compiler error
    rojnet
    10:45 9 May '04  
    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 error
    Ismag
    21:33 11 Jun '04  
    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 error
    Janice Lee
    18:44 17 Jun '04  
    Yes, you need to reinstall Platform SDK. This might be caused by incomplete installation! Rose

    Janice Lee
    GeneralRe: MIDL compiler error
    StefanBrunn
    3:42 21 Dec '04  
    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 error
    Member 3220038
    20:51 13 Aug '08  
    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 .\vbTestCOM.idl
    %CL%
    fatal error C1083: Cannot open source file: '%CL%': No such file or directory
    vbTestCOM.idl
    midl : command line error MIDL1003 : error returned by the C preprocessor (2)

    PLEASE HELP
    Generalyou can just using the "#import" directive to import a typelib or a exe/dll module with typelib resource
    chen3fengx@hotmail.com
    16:42 26 Apr '04  
    eg:
    #import "test.dll" no_namespace
    I's a better way to do that.

    GeneralCoCreateInstance failed
    eric1076
    4:27 14 Oct '03  
    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 would happen, or how to fix it? The VB DLL I am trying to call is registered on the server. The C++ wrapper DLL I created resides in the same folder as the VB DLL. I can provide more detailed info and code if necessary.

    Thank you..
    GeneralRe: CoCreateInstance failed
    Shanjaq
    9:08 30 Nov '05  
    I get this same error.. Author please explain why this could happen!
    GeneralRe: CoCreateInstance failed
    jtholt
    13:23 6 Mar '07  
    I got the same error using VC6 SP5.


    Last Updated 19 Nov 1999 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010