Calling a C++ DLL from Visual Basic

Adding the files

You will now have to add three files to your project, the first being an implementation (.CPP) file, the second an interface/header (.H) file and the third a DEF (allows VB to be able to read the C++ dll function name) file.

Now lets add to the include files the function definitions for the header file. I called the header file for this demonstration c_dll_4_vb.h.

c_dll_4_vb.h

#include <windows.h>
#include <winsock.h>

// Function is used to resolve a domain name to an IP address.
// The return values are: -100 = Incorrect version of Winsock
//                        -200 = Cant resolve domain.
long __stdcall Resolve_Name_To_Ip
    (char *pcDomainToResolve, char szReturnIP[500], int &iSize);

The function defined above will take three parameters:

  • pcDomainToResolve - The name of the domain you are inquiring about.
  • szReturnIP -The variable the IP address will be returned to you in.
  • iSize - The length of IP address being returned without the padding.

Next you will need to add the implementation of the header file to the .CPP file. Remember that when you add the code to the .CPP file make sure you include the header file name (c_dll_4_vb.h).

c_dll_4_vb.cpp
#include "c_dll_4_vb.h"

long __stdcall Resolve_Name_To_Ip
  (char *pcDomainToResolve, char szReturnIP[500], int &iSize)
{
  WSADATA wsaData;					
  LPTSTR CompName = new char[255];
  LPDWORD CompSize = new unsigned long(255);

  struct sockaddr_in dest;
  struct hostent *hp;
  char *dest_ip;

  unsigned int addr = 0;

  strcpy(CompName,pcDomainToResolve);

  if(WSAStartup(MAKEWORD(2,1), &wsaData) != 0)
  {  WSACleanup();
	 return -100;
  }

  hp = gethostbyname(CompName);
  if(!hp)
  {  addr = inet_addr(CompName);	
  }

  if((!hp) && (addr == INADDR_NONE))
  {// Unable to resolve domain ip.
    WSACleanup();
    return -200;
  }

  hp = gethostbyname(CompName);
  if(hp != NULL)
    memcpy(&(dest.sin_addr),hp->h_addr,hp->h_length);
  else
    dest.sin_addr.s_addr = addr;

  if(hp)
    dest.sin_family = hp->h_addrtype;
  else
    dest.sin_family = AF_INET;

  dest_ip = inet_ntoa(dest.sin_addr);
	
  iSize = strlen(dest_ip);
	
  // Allow the string to return to the proper size.
  strncpy(szReturnIP, dest_ip, strlen(dest_ip)); 
	
  dest_ip = NULL;
  hp = NULL;
  addr = 0;
  dest.sin_family = NULL;
  dest.sin_addr.s_addr = NULL;	
  dest.sin_addr.S_un.S_addr = NULL;
  dest.sin_port = NULL;

  delete [] CompName;
  delete [] CompSize;

  WSACleanup();
  return 0;
}

Shew! Now that wasn't so bad. Ok, we have one more file to add data to but this one I swear is a breeze, this is the .DEF file. This file will let VB read the function names from the C++ dll. This is the most important file when working with C++ and VB because without it you will run into all kinds of errors.

So rather than just talking about it let see what this file looks like.

c_dll_4_vb.def
LIBRARY c_dll_4_vb
DESCRIPTION     'A C++ dll that can be called from VB'

EXPORTS
  Resolve_Name_To_Ip @1

You have just completed the C++ dll. All that is left for you to do is compile the dll and it will be ready for use with VB.

So what are we waiting for lets get onto the VB stuff!

You might also like...

Comments

About the author

Kevin Saitta United States

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 [email protected].

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Before software should be reusable, it should be usable.” - Ralph Johnson