65.9K
CodeProject 正在变化。 阅读更多。
Home

初学者教程:从 Visual C++ 调用 Visual Basic ActiveX DLL

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (33投票s)

1999年11月19日

7分钟阅读

viewsIcon

715607

downloadIcon

2762

  • 下载源代码 - 8 Kb
  • 本教程基于MSDN文章 #ID: Q194873。但是,对于初学者来说,阅读这些MSDN文章,至少可以说,可能会令人望而生畏。作为一名Visual C++和Visual Basic程序员,我经常看到的一个最常见的问题是如何从VC++调用VB DLL。好吧,我希望今天能向您展示这一点。我不会过多地介绍COM的基本细节,因为这会花费太长时间,所以假设您已经了解VB、VC++以及一些COM知识。学习起来并不难;只需要一点时间。那么,我们开始吧。

    您需要做的第一件事是启动Visual Basic 6(VB 5 也可以)。在VB运行的情况下,创建一个新的“ActiveX DLL”项目。将项目重命名为“vbTestCOM”,并将类重命名为“clsTestClass”。您可以通过在VB项目资源管理器窗口中单击Project1项(步骤1),然后在属性窗口中单击并选择Name属性(步骤2)来完成此操作。对类执行相同操作。单击类(步骤3),然后单击Name属性,并输入上述名称(步骤4)。到目前为止,您的项目应该与右侧的图片类似

    Naming the Project

    好的,现在我们准备向VB类添加一些代码。单击“工具”菜单,然后选择“添加过程”菜单项。将打开“添加过程”窗口。在此窗口中,我们需要添加一些信息。首先(步骤1),确保类型设置为“函数”。其次(步骤2),输入一个名为“CountStringLength”的函数名。最后,单击“确定”按钮,VB将在类中生成新函数。

    Add Procedure Window

    您应该有一个空的函数可以使用。我们将做的第一件事是指定返回类型和输入参数。将您的代码编辑成如下样式

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

    我们在这里做什么?我们接受一个参数,在这种情况下是String类型,然后通过返回类型(Long)返回长度。我们将输入参数指定为ByVal,这意味着VB将创建此变量的副本,并在函数中使用该副本,而不是默认的ByRef,后者通过引用传递变量。这样,我们就可以确保不会意外修改由调用程序传递给我们的字符串。现在,让我们添加代码。

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

    在第一行代码中,我们正在检查调用程序是否传递了一个空字符串或NULL字符串。如果是,我们返回0作为长度。如果用户确实传递了非空字符串,那么我们将计算其长度并将其长度返回给调用程序。

    现在是保存项目的好时机。接受默认名称,并将其放在安全目录中。我们现在需要编译此项目。转到“文件”菜单,然后选择“生成vbCOMTest.dll...”菜单项。

    Compiling the ActiveX DLL

    编译器将生成一个出乎意料的文件:vbCOMTest.dll。编译器还将自动将新的DLL注册到系统注册表中。VB部分的项目已经完成,现在让我们开始VC++部分。启动VC++,然后从菜单中选择“新建项目”。将出现“新建项目”窗口。选择“Win32控制台应用程序”(步骤1),然后将其命名为“TestVBCOM”(步骤2)。最后,输入要在其中生成此项目的目录(步骤3 - 您的目录将与我输入的不同)。

    VC++ New Project Window

    单击“确定”按钮,将出现“Win32控制台应用程序 - 第1步(共1步)”窗口。将此页面上的所有内容保留为默认值,然后单击“完成”按钮。之后会再次出现一个名为“新项目信息”的窗口。只需单击“确定”按钮即可。现在您应该有一个空的Win32控制台项目。按“Ctrl”键然后按“N”键。将出现另一个名为“新建”的窗口。选择“C++源文件”(步骤1),然后输入此文件的新名称,名为“TestVBCOM.cpp”(步骤2 - 确保选中“添加到项目”复选框,并在下拉组合框中选择了正确的项目名称),然后单击“确定”按钮完成。

    Adding a New C++ Source File

    现在我们将变得更酷!您需要转到Windows的“开始”菜单,导航到“Visual Studio 6”菜单,然后进入“Microsoft Visual Studio 6.0 Tools”子菜单。在这里,您将看到一个名为“OLE View”的图标。单击它。

    Starting OLE View

    OLE View工具将打开。您将看到一个类似于此窗口的窗口

    Starting OLE View

    折叠所有树,如果它们尚未折叠。这将使导航到我们要去的位置更加容易。突出显示“类型库”(步骤1)并展开它。您应该看到一个相当大的列表。我们需要找到我们的VB DLL。现在,还记得我们给项目起的名字吗?是的,我们需要查找vbTestCOM。向下滚动直到找到它。找到后,双击它。将出现一个新窗口 - “ITypeLib 查看器”窗口。我们只对窗口右侧的IDL(接口定义语言)代码感兴趣。选择所有IDL文本,然后按“Ctrl”和“C”按钮将其复制到剪贴板。

    Copying the IDL file

    您现在可以关闭此窗口和OLE View窗口,因为我们已经完成了该工具。我们需要将IDL文件的内容添加到我们的VC++项目文件夹中。转到您告诉VC++创建项目的文件夹,并在那里创建一个新的文本文件(如果您在Windows资源管理器中,可以右键单击目录并选择“新建”,然后滚动到箭头并选择“文本文档”)。将文本文档重命名为“vbCOMTEST.idl”。然后双击新的IDL文件(如果正确命名了具有IDL扩展名的文件,VC++应该会打开它)。现在通过按“Ctrl”和“V”键将代码粘贴到文件中。IDL文本将被粘贴到文件中。到目前为止,一切顺利。现在,直到我们编译它,这个IDL文件才会有太大用处。这样,VC++就可以使用它生成的文件与VB DLL进行通信。我们现在就来做这件事。打开一个DOS窗口,然后导航到您创建VC++项目的目录。进入该目录后,在提示符下,您需要键入以下命令来调用MIDL编译器

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

    按“Enter”键,让MIDL施展魔法。您应该看到类似以下的输出

    Compiling the IDL file with the MIDL compiler

    关闭DOS窗口,然后返回VC++。我们需要将新生成的vbTestCOM.h和vbTestCOM_i.c文件添加到项目中。您可以通过转到“项目”菜单,然后选择“添加到项目”项,滚动到“文件”菜单项并单击它来完成此操作。将打开一个名为“将文件插入项目”的窗口。选择下一张图片中突出显示的两个文件,然后选择“确定”按钮。

    Adding the files generated by MIDL

    这两个文件是由MIDL为我们生成的,VC++需要它们才能与VB DLL通信(实际上,VC++不需要项目中的“vbCOMTest_i.c”文件,但将其保留在项目中以便查看会很方便)。我们现在将以下代码添加到“TestVBCOM.cpp”文件中,所以请使用“工作区”窗口导航到VC++中的该文件。通过双击打开文件,VC++将显示空文件进行编辑。

    Updated Workspace Window

    现在将以下代码添加到“TestVBCOM.cpp”文件中

    #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();
    }
    

    如果所有代码都正确输入,请按“F7”键编译此项目。项目成功编译后,按“Ctrl”和“F5”键运行它。在C++代码中,我们包含了MIDL创建的“vbTestCOM.h”文件,“Comdef.h”文件用于_bstr_t类支持,以及“iostream.h”文件用于“cout”支持。其余的注释应该能解释所发生的事情。这个简单的教程展示了使用COM集成VB和VC++应用程序的良好效果。实际上并不难。

    © . All rights reserved.