CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jul 2009
    Posts
    8

    Calling Visual Basic 2008 functions from VC++2008

    Hi,

    I am new to mixed language programming and need to call a VB 2008 function (for which I have the source code) from a C++ code. I have Visual Studio 2008 with VB and VC++.

    I searched through the web for several days now and getting extremely confused and frustrated because all methods seem to either imply that using VB6 would be simpler (eg, http://support.microsoft.com/kb/194873 which I am unable to follow in VS2008 because there are no activeX dlls..), or give incomplete solutions that I am unable to get compiled (eg, http://msdn.microsoft.com/en-us/libr...zx(VS.71).aspx).

    Please, could somebody post a working example on how to call a simple VB code (below) from a simple C main unit (also below) using Visual Studio 2008?

    I just want the simplest example that works and will build up from there - at the moment just getting nowhere after several days of trying solutions from the web :-( I have previously worked with COM objects etc, but just cant get my head around the C++/VB coupling and dont know the syntax for it..

    Many thanks in advance!

    --------------
    ' VB code to be called

    Option Explicit On
    Public Class Class1
    Public Function vbfunk(ByVal x As Integer) As Integer
    MsgBox(x)
    vbfunk= x
    End Function
    End Class

    ----------------------------

    // C code to call VB

    #include "stdafx.h"
    #include <stdio.h>
    #include <stdlib.h>

    #import "vbdll.tlb" no_namespace

    int main()
    {
    int rst;

    // I understand I need a COM-type DLL??
    //CoInitialize(NULL);

    // some connection to add here
    rst=vbfunk(1);

    //CoUninitialize();

    return 1;
    }

  2. #2
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Calling Visual Basic 2008 functions from VC++2008

    http://support.microsoft.com/default.aspx/kb/817248

    This article describes how to create VB .NET project and register it for COM interoperability. Having COM server, you can call it from C++ using standard COM client code (#import, CreateInstance etc.).

  3. #3
    Join Date
    Jul 2009
    Posts
    8

    Re: Calling Visual Basic 2008 functions from VC++2008

    thank you very much Alex - I am starting to get there. Can you recommend a similar "how to" knowledge article for writing the COM interface - as I mentioned I am quite new to this and though I had used other peoples COM code I would like to have a cleaner understanding.

  4. #4
    Join Date
    Jul 2002
    Posts
    2,543

    Re: Calling Visual Basic 2008 functions from VC++2008

    Writing the COM interface? In what language?

  5. #5
    Join Date
    Jan 2007
    Posts
    90

    Re: Calling Visual Basic 2008 functions from VC++2008

    there are lots of COM article on codeguru and codeproject in c++ and other language

    regards

  6. #6
    Join Date
    Jul 2009
    Posts
    8

    Re: [RESOLVED] Calling Visual Basic 2008 functions from VC++2008

    I attach a working example - hopefully somebody may benefit from my 10 consecutive hrs of figuring this out ... jeez I am slow sometimes ...

    Alex - thanks for pointing me in the right direction - I previously used COM interfaces from Fortran (yikes, a bit embarassing to admit on this forum :-)) and so here I had to learn the C++ syntax (as well as the VB syntax for implementing the Interface) - too many new things just to use some dialog boxes and automation scripts!

    The posts by Siddhartha

    http://www.codeguru.com/forum/archiv.../t-364152.html
    http://www.codeguru.com/forum/showthread.php?t=354953

    were helpful but didnt seem to work here (they result in runtime Debug Assertion failure p!=0).

    The http://msdn.microsoft.com/en-us/libr...zx(VS.71).aspx has an almost-working code that had to be modified (evolution?). I created a shorted version to highlight the concepts.

    The 2004 blog http://charlesvaz.blogspot.com/2004/...ct-from-c.html suggested an instantiation procedure with better error checking properties (?).

    The limitations of the code below are:

    1) the VB namespace appears not actually used (though all procedures work). I am unsure why that is: The MSDN examples have them, and consequently do not compile ...

    2) The "smart pointer" approach doesnt work... any ideas anyone?

    3) As I posted on http://www.codeguru.com/forum/showthread.php?t=481490, there seems to be a problem when the code is modified to pass string arguments (if C++ sends a string exceeding 30 chars, VB receives a blank 0-length string, bizarre..)

    Any idea what could be causing these problems? thanks in advance as usual!

    ===============================

    // CPP08_CONCLR_CALLZ_VB08_DLLCLASSLIB_1.cpp : main project file.
    // This file connects to a VB Class Library DLL using the COM approach

    // Can be built as a C++ Win32 or CLR console project in VS2008 (not sure whats the diff??).
    // With appropriate changes, the approach below can probably be built as DLL, etc.

    #include "stdafx.h"
    #include "iostream"
    //#include "atlbase.h" // needed only for CComQIPtr (methods 1 & 2, dont work here anyway)
    using namespace std;

    #import "path\VB08_DLLCLASSLIB_1.tlb" raw_interfaces_only no_namespace
    //using ComClass1Lib // does not work: VB-DLL namespace seems unaccessible ...

    int main()
    {
    cout << left << "Inside C++ main" << endl;

    HRESULT hr = CoInitialize(NULL);

    int ok=-10;

    //-----------------------
    // Siddhartha's methods from http://www.codeguru.com/forum/archiv.../t-364152.html
    // Do not seem to work here ...
    // Use Smart pointer (only for methods 1 and 2)
    // CComQIPtr <IComClass1> pIComClass1;

    // Method 1: Using Prog Id [Debug assertion failure p!=0 in VB myFunction]
    // if (SUCCEEDED (pIComClass1.CoCreateInstance (L"VB08_DLLCLASSLIB_1.ComClass1")))
    // {ok=1;}
    // else
    // {ok=50;}

    // Method 2: Using Class Name [Debug assertion failure p!=0 in VB myFunction]
    // if (SUCCEEDED (pIComClass1.CoCreateInstance (__uuidof (ComClass1)))){ok=1;}
    // else {ok=50;}
    //-----------------------

    // Method 3 (adapted from MSDN knowledgebase
    // http://msdn.microsoft.com/en-us/libr...zx(VS.71).aspx
    // IComClass1Ptr pIComClass1(__uuidof(ComClass1));
    // _ComClass1Ptr pIComClass1(__uuidof(ComClass1)); // interchangeable

    // Method 4 (from a 2004 blog) - Gives best error checking capabilities
    IComClass1Ptr pIComClass1 = NULL; hr = S_OK;
    if (SUCCEEDED (pIComClass1.CreateInstance( __uuidof(ComClass1 ) ))){ok=1;}

    if(ok==-10) {cout << left << "UNKNOWN status in COM" << endl;}
    else if(ok==1){cout << left << "SUCCEEDED IN CreateInstance"<<endl;}
    else {cout << left << "ERROR IN CreateInstance"<<endl;}

    // Initialize variables to send to VB
    long x=10;
    VARIANT_BOOL reslt=false;

    cout << left << "BEFORE" << endl;
    cout << left << "x=" << x << endl;
    cout << left << "reslt=" << reslt << endl;

    // Call the VB routine from the DLL
    hr=pIComClass1->myFunction(&x,&reslt);

    // ideally, check hr==0 here, if hr!=0 then error occured

    // Check variables returned by VB
    cout << left << endl << "BEFORE" << endl;
    cout << left << "x=" << x << endl;
    cout << left << "reslt=" << reslt << endl;

    CoUninitialize();

    return 0;
    }

    ===============================

    ' VB script to be built as Class Library DLL in VS2008.

    ' 1. File > New > Project > Visual Basic > Class Library > "VB08_DLLCLASSLIB_1"
    ' 2. Delete file Class1.vb
    ' 3. Project > Add Class > COM Class
    ' 4. Save the COM GUIDs that are automatically generated in the COM class file in step 3
    ' 5. Paste the script below into the COM class file (overwrite everything)
    ' 6. Paste your (saved) COM GUIDs into the COM class file
    ' 7. Ensure 'Register for COM interop' is clicked in project settings > compile

    ' Comments:
    ' 1. The full Namespace with Implementation is good programming practice, but the
    ' not using them is probably ok as well - as long as the Interface is implemented!

    Option Explicit On

    Namespace ComClass1Lib

    Public Interface IComClass1
    Function myFunction(ByRef x As Integer) As Boolean
    End Interface

    <ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
    Public Class ComClass1
    Implements IComClass1

    #Region "COM GUIDs"
    ' These GUIDs provide the COM identity for this class
    ' and its COM interfaces. If you change them, existing
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "c91a80a9-07d4-41d6-95d6-af91925f5f00"
    Public Const InterfaceId As String = "680d8540-ec24-4b63-939c-93af02050728"
    Public Const EventsId As String = "f04ad9b1-c78e-4be5-b524-3c06ef3f2554"
    #End Region

    ' A creatable COM class must have a Public Sub New()
    ' with no parameters, otherwise, the class will not be
    ' registered in the COM registry and cannot be created
    ' via CreateObject.
    Public Sub New()
    MyBase.New()
    End Sub

    Public Function myFunction(ByRef x As Integer) As Boolean _
    Implements IComClass1.myFunction
    MsgBox(x)
    x = x + 1
    Return False
    End Function
    End Class

    End Namespace

    ===============
    Last edited by kangazzz; July 24th, 2009 at 04:10 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured