我用的是VS2005版本,编写了一个VB的程序,要在VC中调用其中的函数接口。问题是如何将VB的函数接口公开,在VC里需要用__declspec(dllexport)语句来显式的声明,那么在VB中如何声明?另一个问题是,如何在VC中将VB的dll文件载入,我用了#import语句,但是链接失败,因为dll文件不被编译器识别。

解决方案 »

  1.   

    最好以COM方式的来调用VB的DLL.
      

  2.   

    是考虑用VC COM智能指针的方式来调用VB的DLL,可是在用#import语句时候出错,无法识别导入的DLL文件,而用REGSVR32命令注册DLL文件时候,又提示找不到DLL REG server的输入点,所以无法注册。
      

  3.   

    就用COM的方法来调用
    如下面是在VC中调用XMLHTTP的范例//这里是DLL入口
    #import "C:\WINDOWS\system32\msxml.dll"
    #import "C:\WINDOWS\system32\msxml2.dll"using namespace MSXML2;
    HRESULT ComInit();
    #include "stdio.h"
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        ComInit();   //调用下面初始化COM的函数
        IXMLHTTPRequestPtr xmlrequest;        //定义变量
        xmlrequest.CreateInstance("Msxml2.XMLHTTP");    //这里有点像VB的CreateObject创建对象
        //这里就像VB中正常的使用XMLHTTP对象了
        xmlrequest->open(_bstr_t("GET"),_bstr_t("http://www.baidu.com/s/index.asp?wd=vc+Com&tn=site888_1_pg&cl=3&ie=utf-8"),_variant_t("false"));
        //xmlrequest->send(_bstr_t("wd=vc+Com&tn=site888_1_pg&cl=3&ie=utf-8"));
        xmlrequest->send();
        BSTR bstrbody;
        xmlrequest->get_responseText(&bstrbody);
        _bstr_t bstrtbody(bstrbody);
        MessageBox(0, (LPCTSTR)bstrtbody, "OK", MB_OK);
        return 0;
    }
    //这里是初始化COM
    HRESULT ComInit()
    {
        HRESULT hr = S_OK; 
        if FAILED(CoInitialize(NULL)) 
        {
            CoUninitialize();
            hr = E_UNEXPECTED;
        }
        return hr;
    }虽然我举的例子是VC调用XMLHTTP的,但是与调用你自己用VB写的COM组件差不多。
    主要就是:
    1、申明入口
    2、初始化COM
    3、定义变量
    4、创建对象
    5、使用对象
      

  4.   

    谢谢SupermanKing,那么在VB中需要怎样的声明,才能保证生成的DLL文件可以被VC import呢?我现在在这个问题上被卡住了
      

  5.   

    创建 ActiveX DLL 以类的形势开发就可以了
      

  6.   

    还有,VB编译DLL时也会有lib文件的
      

  7.   

    我举个例子。
    先说说VB开发一个COM组件。
    用VB新建一个ActiveX DLL 工程,
    然后修改工程名称为 MyVB
    再修改默认的类名为 DEMO
    然后再向类中添加一个函数作为测试用,如:Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
    '取得当前系统登陆的用户名称
    Public Function GetMyName() As String
        Dim UserName As String
        UserName = String(128, " ")
        GetUserName UserName, 128
        UserName = Trim(UserName)
        GetMyName = Left(UserName, Len(UserName) - 1)
    End Function然后保存工程并生成DLL文件,这时已经可以通过VB动态调用这个COM组件了。
    如果在VB里,可以这样调用:    Dim MyObj As Object
        Set MyObj = CreateObject("MyVB.DEMO")
        MsgBox MyObj.GetMyName
        Set MyObj = Nothing这时可以看出,MyVB 是 COM 组件名称,DEMO 是 COM 组件的类名称,
    而 VC 里调用可以这样做,如://下面是指定DLL的位置
    #import "C:\我的程序\VC调用COM\MyVB\MyVB.dll"
    using namespace MyVB; //这里是COM组件名称
    HRESULT ComInit();
    #include "stdio.h"int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    ComInit();
    _DEMOPtr MyObj; //注意这里,类名虽然是DEMO,但是定义声明应该是“_类名Ptr”来定义对象
    MyObj.CreateInstance("MyVB.DEMO"); _bstr_t vRsinfo; //VB的String在VC里可以用_bstr_t类型,所以就用_bstr_t类型来接返回参数
    vRsinfo = MyObj->GetMyName(); //这里使用对象方法取得当前用户名称 MessageBox(0, vRsinfo, "OK", MB_OK);
    return 0;
    }HRESULT ComInit()
    {
    HRESULT hr = S_OK; 
    if FAILED(CoInitialize(NULL)) 
    {
    CoUninitialize();
    hr = E_UNEXPECTED;
    }
    return hr;
    }以上 VC6 代码是建立一个 Win32 应用程序(Win32 Application),
    选择 An empty project,然后再添加并添加一个 C++ Source File,
    在 Windows XP 下测试通过。
      

  8.   

    vb.Net中编译的dll并不是标准dll,更不是COM。我习惯叫他程序集。
    如果要让vc能够调用vb.net编译的dll,那就显示的把dll编译成COM。具体方法请参考:
    http://blog.csdn.net/mysticboy/archive/2007/09/30/1808212.aspx
      

  9.   

    更正一下吧,严格的来说.net的dll是COM,但不是我们常规意义上的ActiveX。
      

  10.   

    感谢各位,原先的程序已经用VB6重新实现后通过COM让VC调用了,越来越感觉微软实在是个流氓了