Library tutorials & articles

Calling a C++ DLL from Visual Basic

Introduction

There have been projects I have been on in the past where there was certain functionality I needed but could not get from VB, or I had to do a complete workaround to get the functionality I could get from C++ very easily. In this tutorial I will show you how to create a C++ dll that you can call from VB. I figure instead of doing the norm, "HELLO WORLD", or "ADD NUMBER", routine I will show you how to resolve a domain name to an IP address and return that IP address back to VB, this is a little advanced for the beginner but if you have some C++ experience it wont be that bad.

For this example I will be using VC++ 6 so if you have that IDE then you will be right at home and in the case you do not use that IDE then just try to follow along and enjoy the ride!

Ok, you will first have to create a new dynamic link library project. After you create this project you will be prompted on what kind of DLL, just click empty.

After that is complete you will have to add the library ws2_32.lib to the project under project-> settings -> link -> object/modules library or the code below will not compile! Believe me when I tell you this as I had the fun of learning this the hard way and it was a nightmare.

Comments

  1. 23 Jul 2009 at 09:57

    Hello, I found this article very interesting!

    I'm trying to call some functions of a C++ DLL the same way you did in your article but I get an error that says "impossible to find the entry point for the function". I don't know why. Could you help me?

    Thank you.

  2. 21 Feb 2009 at 14:04
    Hi, Thank you for your post..this is really a nice article.. My Computer Guide
    Your first stop for a healthy computer! Proccess information, driver downloads, dll files, information about virusses and pc manuals.
  3. 31 Aug 2008 at 13:56

    Check out this article:
    http://blog.rednael.com/2008/08/29/MarshallingUsingNativeDLLsInNET.aspx

    It's an in-depth article that shows you how to marshal any native (or C++) DLL. It shows which types are interoperable, how to import a DLL, how to pass strings and how to de-reference pointers.

    It's quite easy.

  4. 09 Dec 2005 at 16:33

    thank you very much for this code. It resolves all my problems and errors. khalil from france.

  5. 25 May 2005 at 08:30

    This program is very useful for me, you are very terrific.  Thanks

  6. 20 Apr 2005 at 18:09

    Hi Caripito,


    I guess what you need is to see if there's some VBA function to return the location of the current workbook. I don't use Excel/VBA hardly at all, so I'm not  familiar with any such function.


    You say there is a "ThisWorkbook.Path" in Excel VBA?  Seems like it would do what you need - what does it return? When you say it doesn't work for you, what is the error?


    Cheers,


    - Chuck Somerville

  7. 20 Apr 2005 at 18:01
    Hey Chuck, thank you very much for answering me... I already know haow to add a DLL in Visual Basic, in fact I guess  it is hte same as stand alone VB... I do this:

    Public Declare Convert Lib "Blue.dll" (ByVal a as Byte) as Bool  

    ---- where Convert is the function and Blue.dll is the DLL that have to be in System32 folder in Windows...

    The problem is that I need to place the DLL in the same folder as the Workbook to make easy the installation and use, but I don't know how to write the sentence... In other situations I have used App.path or ThisWorkBook.path but in this  declaration isn't work...

    The program works perfectly when the DLL is in the Windows System32 folder... And if I write the whole path it works too, but the problem is that this path is not going to be always the same, because it depends on where the user place the folder...

    So, if you happen to get the problem and have any clue, please write me as soon as possible...

    Thanks again

    Caripito
  8. 20 Apr 2005 at 16:25
    Quote:
    [1]Posted by caripito on 20 Apr 2005 09:55 AM[/1]
    Hello... I have some similar troubles.. I need to declare a DLL in a MACRO in EXCEL using Visual Basic, and I need to set the default path in the same path the WORKBOOK is... Can you please help to do that?... I have tried everything but Visual Basic always pop up an ERROR...

    Thanks a lot...

    Caripito


    Well, VBA within Excel is not the same as a stand-alone VB program with an installer. My previous comments relate to having the installer install the app and the DLL.

    There is one way to "hook up" your VBA app to some DLLs (ones that  provide "object libraries" to "Automation Controllers" like Visual Basic, having been registered as such with Windows).  Search the VBA help for the topic called "Check or Add an Object Library Reference" to see how to add a reference to a DLL which has had an "object library" or a "type library" registered with Windows.

    I believe you can also use a "Declare" statement to name a DLL which has been written to be callable from VB, but the location is going to have to be one of the places I mentioned earlier, and the location of the workbook is not in the DLL search path. (The workbook is not "executing" - Excel, including VBA within Excel, is executing from the directory where Excel.EXE lives.) Look in VBA help for the "Declare Statement" topic.

    Both the above topics can be found in the help if you go to the "Index" tab and enter "DLL" in the "Keywords" area.

    - Chuck Somerville
  9. 20 Apr 2005 at 09:55
    Hello... I have some similar troubles.. I need to declare a DLL in a MACRO in EXCEL using Visual Basic, and I need to set the default path in the same path the WORKBOOK is... Can you please help to do that?... I have tried everything but Visual Basic always pop up an ERROR...

    Thanks a lot...

    Caripito
  10. 25 Feb 2005 at 05:41

    Quote:
    [1]Posted by relliott on 28 Oct 2004 09:12 AM[/1]
    I found this article extremely helpful.  It was exactly the right level of detail.  However, is it necessary to put the path to the dll in your vb code?  Isn't it more common to put the dll in a folder that windows knows about (for example on my Widnows 2000 machine, there's hundreds of dll's in my Windows\System32 folder).  This way we could just have vb find the dll with the name cdll4_vb.dll.  The reason I ask is that I may deploy this to other versions of Windows, and I'm concerned that other versions of Windows keep their DLL files in a different location.


    You can install the DLL in the directory you install the VB app into, if it's a DLL only you will need.


    You can install it to the windows\system32 directory if it is a DLL shared by other apps.


    When you run the Package and Deployment Wizard in VB to make your installer, you get to specify details about the DLL, like where to install it ({appdir} or {win\sys32} or something like that - it's a pull-down with symbols for those locations so the installer will point it all to the right place at each installation). You also get to say whether it's a DLL that may be shared by other apps. If so, it won't be un-installed untill all the other apps that use it are uninstalled as well.


    Your app will find the DLL in either location... DLL search rules are a little like .EXE program search rules in DOS...


    1. look in the dir your program launched from.
    2. look in every location in the PATH.
    3. look in the windows directory (not necessarily named C:\windows).
    4. look in the windows\system32 directory.


    There's pretty good help on all this in the VB6 help system.


    - Chuck Somerville

  11. 28 Oct 2004 at 09:12

    I found this article extremely helpful.  It was exactly the right level of detail.  However, is it necessary to put the path to the dll in your vb code?  Isn't it more common to put the dll in a folder that windows knows about (for example on my Widnows 2000 machine, there's hundreds of dll's in my Windows\System32 folder).  This way we could just have vb find the dll with the name cdll4_vb.dll.  The reason I ask is that I may deploy this to other versions of Windows, and I'm concerned that other versions of Windows keep their DLL files in a different location.

  12. 18 Oct 2004 at 17:01

    I'm pretty sure strings are handled differently in VB than in C++.

  13. 25 Mar 2004 at 09:49

    Thank you very much, your article help me so much. I create the 3 files that you recomended and put the code into the files and after I go to the Visual Basic and put the code, and when I run program, image what happen!!!! It run perfectly.


    Well, thank you very much again, and if you need something only ask me.


    Regards,
    Wilton Filho

  14. 11 Dec 2003 at 21:35

    Hi,


    I am trying to invoke a VB application from C++ dll using the ShellExecuteEx command. The problem is when I execute the program, the VB application comes up, but when I try to move the form, the parent window goes blank. Same thing happens if I switch between windows. Can anyone please guide me how to invoke a VB application from a C++ dll without much changes to my existing code.


    Snippet of my code:
                                   HWND lhwndFound;
           LPSHELLEXECUTEINFO l
    sei=new SHELLEXECUTEINFO;
           lhwndFound=GetActiveWindow();
           if(l
    hwndFound != NULL)
           {  
               lsei->cbSize=sizeof(SHELLEXECUTEINFO);
               l
    sei->fMask = SEEMASKNOCLOSEPROCESS;
               lsei->hwnd =lhwndFound;
               lsei->lpVerb = "open";
               l
    sei->lpFile = "MyApplication.exe";
               lsei->lpParameters = "Src";
               l
    sei->lpDirectory = lconfigpath;
               l
    sei->nShow = SWSHOWNORMAL;
               l
    sei->hInstApp = NULL;
               ShellExecuteEx(l_sei);  


               WaitForSingleObject(lsei->hProcess , INFINITE);
               delete l
    sei;
           }


    Thanks in advance


    Regards,
    Rashmi

  15. 14 Oct 2003 at 12:16
    Generally in the project settings I'll use the following settings to debug (for the "Debug" settings):

    Under the "Link" tab:
    In the "General" category, enable "Generate debug info".
    In the "Debug" category, enable "Debug info".

    Under the "C++" tab:
    In the "General" category, enable "Generate browse info", and set the "Debug Info" to "Program Database for Edit and Continue".
    In the "C++ Language" category, enable "Enable exception handling".
    In the "Listing Files" category, enable "Generate browse info".

    Under the "Browse Info" tab:
    Enable "Build browse info".

    Then just use the Debug version instead of the release version and you can step through on errors.

    Note that if you want to step through part of the code even if it doesn't generate an error, just add VERIFY(0); wherever you want to step through.

    John
  16. 23 Jul 2003 at 05:57
    I am developing interface in VB for an application program written in VC++. DLL of C++ code is called in VB. I met a strange problem. I have tested the conversion between structure in C++ and user defined type in VB successfully, which includes another embedded structure and a string as member variables. When I try to add one string member into the embedded structure, VB has a problem. It prompts" VB encountered a problem, .." and aborts completely. Can anyone tell me why this happens? Thanks.
  17. 18 Jul 2003 at 16:06
    I'm having trouble passing 9 variables into C++.  It works fine if I just pass 2 or 3.  Any idea why it won't work when passing more than a few variables?
  18. 29 May 2003 at 04:12

    Thanks, it was a very usefull for me.
    However I still have one problem...


    I'm working with Visual Studio .Net, and I want to debug both, the C++ DLL and the Visual Basic application at once.


    The C++ DLL in the article is linked to the applications in a 'dynamic link', that is simmilar to calling LoadLibrary from a C++ application. Is there a 'static link' way as well?
    i.e. is there a way to link the .lib file of the DLL to the Visual Basic application, so that when reaching the call to the C++ function when debugging the Visual Basic application, it will be possible to step in to the C++ code etc?


    Thanks in advance
     
           Israel

  19. 21 May 2003 at 10:59

     This post was a great time saver for me. Only thing to keep in mind is that if you
    declare the DLL functions as "Private" within a module, you won't be able to call them
    directly from any other place. VB complains "Sub or Function not defined"... for what it's worth.

  20. 05 Apr 2003 at 10:44
    My dll compiled without any problem for Debug.  When i tried to compile a release version i got this mess in my output window.

    Linking...
      Creating library Release/Dll.lib and object Release/Dll.exp
    Dll.obj : error LNK2001: unresolved external symbol _inet_ntoa@4
    Dll.obj : error LNK2001: unresolved external symbol _inet_addr@4
    Dll.obj : error LNK2001: unresolved external symbol _gethostbyname@4
    Dll.obj : error LNK2001: unresolved external symbol _WSACleanup@0
    Dll.obj : error LNK2001: unresolved external symbol _WSAStartup@8
    Release/Dll.dll : fatal error LNK1120: 5 unresolved externals
    Error executing link.exe.

  21. 10 Feb 2003 at 14:05

    http://www.mvps.org/vcfaq/il/3.htm actually deals with one of the problems mentioned.  Not sure whether a wrapper can be written in this case ...


    dwilson

  22. 06 Feb 2003 at 07:20

    How to include dll file in visual basic 6.0 program?


    Thanks in advance
    bloodlustangel

  23. 23 Jan 2003 at 22:07

    I am use studio to do the coding and prompt out this exception
    An unhandled exception of type 'System.DllNotFoundException' occurred in WindowsApplication1.exe


    Additional information: Unable to load DLL (C:\jacky\JavaTest\extendDLL\Debug\extendDLL.dll).


    but it is there already

  24. 20 Jan 2003 at 17:11

    I'd bet it had something to do with the following:


    http://www.mvps.org/vcfaq/il/2.htm


    Since you don't have the source of the DLL that you can not change this directly but you could wrapper the _cdecl declared DLL in a C++ object which is declared as _stdcall .


  25. 10 Jan 2003 at 03:38
    Have a look at the following page, might help http://www.vb2themax.com/HtmlDoc.asp?Table=Articles&ID=60
  26. 05 Jan 2003 at 22:33

    Hi there,
     have you discovered how to solve the problem of the entry point? Would be appreciative if you could share with me.


    Cyndi

  27. 02 Jan 2003 at 04:23


    I tried the code and found it working OK.


    but what my problem is that i have to call  DLL functions (dll provided by the card manufacturere) of a PCI card from my VB code.


    I adopted the same code with some modification to test a single function of dll and it works but the function  while in execution throws an  exception and pops up a message that PCI-XXX card not found.


    while that same dll function is working properly when used in a sample program in VC++ (provided by the manufacturer).


    so can any body tell me that how to debug a dll so that i can rectify the problem.

  28. 06 Dec 2002 at 12:53

    everything seems to work. But when I run VB nothing really happens. I just get a blank window box.  I think my VB isn't set up right. All I did was copy and paste the code into my VB code form. I didn't set up any buttons or text boxes. Am I supposed to?


    Please help. THanks!

  29. 21 Nov 2002 at 00:03

    I think this article is very useful to me, as a new vb programmer, however, i got this message when i run the VB


    'Bad dll calling conversion'


    do anyone know what is the reason?

  30. 26 Sep 2002 at 21:39

    I have very basic knowledge in Visual C++.I created the dll file and it is correctly compiled.
    But when i execute my vb program,I'm getting an error.......Can't find dll entry point ResolveNameTo_In.
    Please help

  31. 13 Sep 2002 at 13:39

    Can i do a *.dll in Borland c/c++ 3.0 , (dos) , i want to make want to use all the port of my PC ( COM1 , LPT1, USB , etc.
    I have a problem , i dont  know how to make it , can you tell me how ?


    Thanks


  32. 30 Aug 2002 at 00:23

    Actually you can call a .dll in VBScript, however I am not sure that you can create them like this in C++ (maybe you can, I haven't done it that way exactly).  You need to create an ActiveX Dll in Visual Basic, simply write a function, then goto File and compile your .dll.  Remember the class and project name.  In ASP you can do something like this.


    <%


    Dim x
    Set x = Server.CreateObject("Project1.Class1")


    If x.Check(1) = 1 Then
       Response.Write("Correct")
    End If


    Set x = Nothing


    %>


    Hope This Helps

  33. 13 Aug 2002 at 07:35

    Can a dll which is created using _cdecl be used in VB


    I have the following code:


    BOOL APIENTRY DllMain( HANDLE hModule,
                          DWORD  ulreasonfor_call,
                          LPVOID lpReserved
                                  &nbsp
    {
       return TRUE;
    }


    extern "C" __declspec(dllexport) bool a(char* lpszPathName)
    {
    ....
    ....
    }

  34. 07 Aug 2002 at 14:35

    I called the dll CVB.dll, i made a CVB.DEF file "
    LIBRARY C_VB
    DESCRIPTION     'A C++ dll that can be called from VB'


    EXPORTS
     ResolveNameToIp @1
    " and no go, says it cannot find the entry point "Resolve
    NameToIp".


    I got by this problem by using dllexport and the extern "C" prefix, no need for a .DEF file?


    Secondly Subs work fine under this method, however when I do get a function to 'work' it doesnt, tells me bad calling procedure, I had thought perhaps the [extern "C"] and different calling convention of dllexport [declspec( dllexport )] were responsible but when I use [stdcall] same problem. I suppose im on my own to sort that out.


    got it working via the PASCAL calling convention..
    ///snippet


    (Error 49)
    Your program is calling a routine in a dynamic-link library (DLL) that either is being passed the wrong type or number of arguments or does not use the Pascal calling convention. Make sure that the arguments passed to the DLL routine exactly match the arguments expected by the routine. If the DLL routine expects arguments by value, then make sure ByVal is specified for those arguments in the declaration for the routine.


    snippet///


    extern "C" <return-type> __declspec( dllexport ) PASCAL func(...)


    perhaps thats useful to someone who runs across the same problems as I.

  35. 29 Jul 2002 at 09:29

    Hi all,
    'How do I create a dll in C++ and call it from VB?'  was an article which can be called Simply SUPERB by its simlicity and elegance. Very helpful and informative.
    Thank you Kevin Saitta. It was a nice work.


    Regards,
    Jeri.

  36. 29 Jul 2002 at 08:20

    You can't call a DLL from VBScript, needs to be VB or VBA.


    Regards,


    Shifty

  37. 27 Jul 2002 at 01:04
    I have followed the article to create the dll file and it is correctly compiled. But when i use my ASP program (VBScript) to test it, cannot get the correct output.......What is the problem here???

    Here is the ASP code:

    <HTML>
    <HEAD>
    <TITLE>Testing page</TITLE>
    </HEAD>
    <BODY>
    <%
     Private Declare Function Check _
     Lib "D:\inetpub\H63080\TryItOut\Debug\TryItOut.dll" _
     (ByVal input As Integer) As Integer

     Private Sub test()
     
       If Check(1)=1 Then
          Response.Write "Correct."
       End If
       
     End Sub
    %>  
    </BODY>
    </HTML>

    Can anyone help me out in this? Thanks a lot!  
  38. 02 May 2002 at 05:17
    It was an very usefull information for me! Thanx ....
  39. 18 Apr 2002 at 01:14

    very nice article, thank you. but it's not really c++ with object et al. i would love to know how to instantiate objects in vb whose underlying classes are defined and implemented in a c++ dll.

  40. 15 Apr 2002 at 15:30

    lol .. oh well

  41. 15 Apr 2002 at 15:16

    Never mind...I didn't see the text ResolveNameTo_Ip. Now it all makes sense!!

  42. 15 Apr 2002 at 14:15

    As far as I am aware, the declaration would be valid providing there was a function called "ResolveNameTo_IP" matching the declaration in the DLL.... however, I'm not quite sure how functions in different classes come into the api declarations....

  43. 15 Apr 2002 at 14:09

    What if there were more than one function available? Would the above VB declaration still been valid?

  44. 15 Apr 2002 at 14:06

    Surely "Declare Function ResolveNameTo_Ip" is telling VB that there is a function with that name in the DLL? If there is no Alias attribute, VB assumes that the function declaration is the same as in the DLL......

  45. 15 Apr 2002 at 13:23

    I love reading articles that the source code actually works on. One thing...


    Private Declare Function ResolveNameToIp _
         Lib "C:\Program Files\Microsoft Visual Studio\MyProjects\c
    dll4vb\Debug\cdll4_vb.dll" _
                        (ByVal pcDomainToResolve As String, _
                        ByVal szReturnIP As String, _
                        ByRef iSize As Integer) As Long


    How did VB know there was a function called ResolveNameTo_Ip available int he DLL. I understand the .def file indicated it, but in most win32 declarations the function name would have been included. If you notice above, it wasn't in this case?

  46. 09 Apr 2002 at 02:18

    Just what I was looking for!

  47. 01 Jan 1999 at 00:00

    This thread is for discussions of Calling a C++ DLL from Visual Basic.

Leave a comment

Sign in or Join us (it's free).

Kevin Saitta Kevin Saitta is an independent Database/Programming consultant specializing in full life cycle development and database design. You can contact Kevin through the Internet at kev@kbaseonline.com.

Related discussion

Related podcasts

  • Christian Beauclair

    14 mai 2008 (�mission #0074) ::.Christian Beauclair: Stratégies de migration VB6 vers .NET Nous discutons avec Christian Beauclair des stratégies de migration VB6 vers .NET. Entre autres, nous discutons comment utiliser le "VB 6 Code Advisor" et le "Interop Forms Toolkit" pour ajouter la puiss...

Want to stay in touch with what's going on? Follow us on twitter!