I'm normally a VB.Net/C# guy but because of a third party dll that isn't working in .Net, I'm having to interact with it using C++. I'm able to read and understand (for the most part) C and C++, but I've never actually written any code in it.

The third party dll contains 10 functions that I have to interact with but I cannot figure out how to access them. In VB/VBA I would use "Declare Function/Sub name Lib "library"" but I don't know how to do that in C++.
I've come across the HINSTANCE, LoadLibrary, GetProcAddress("ProcName") but i don't know how to actually call the procedure.

Could someone provide the code that would allow me to do that?

Recommended Answers

All 12 Replies

I'm really new to C++ as well, so I don't know how to establish the actual link to a library yet. What I do know is that what you are looking for is a header file designed for your library. In C++, "header" files (*.h files) contain various function declarations, type definitions, class definitions, etc. and are frequently used to help you link to and use libraries.

In general, to use a header you use an "include" statement such as #include <headerName> or #include "headerName.h" .

I can't give you exactly the statement you'll need because I don't know anything about your library. If you provide the name of the library, another member may be able to give you more specific suggestions.

Once you have your header(s) in place. It's simply a matter of entering the function's name and argument(s) where you need them.

Sorry about double-posting, very l8 after thought...

I would look into your language of choice's help file. There may be a keyword that you can use in your declare statement(s) to specify a different calling convention that is compatible with the library.

I know that in FreeBASIC you can use the keywords "cdecl", "stdcall", and "pascal" in your function/sub declarations and definitions to change the way the system manipulates them on the stack. When using the "cdecl" keyword in either your local declaration or your header/wrapper, you can usually access libraries that are set up with a C-style calling convention from FreeBASIC.

I expect you should be able to call the functions in the dll from vb.net. As mentioned by the other helpful poster, you will need some kind of header file from the dll to see what the exported functions look like. Having seen that, you should be able to generate vb declares. I'm not that terribly familiar with .NET (I don't like it although in the past I studied it a lot), but I call C functions from my programming language of choice (PowerBASIC) all the time. The main issue is translating variable types and calling conventions. For example, all basic languages pass variables by reference, whereas C family languages pass parameters by value. Once you iron out such problems it works very well to do such mixed language programming.

Do you have any idea what some of the function prototypes are?

Yeah, I've been provided the functions required and a structure to use. Unfortunately, the third party DLL doesn't like .Net when it passes the structure and throws an error. The error only says "An external component has thrown an error."

I think I've found a solution using VB6 since I can't get up to speed fast enough with C++ (and not for lack of trying).

Well, I'm glad to hear you are making progress. However, just for your information I don't believe its necessary to use LoadLibrary() and GetProcAddress() to interact with the dll in C/C++ or most other languages. Just using proper function declares should be enough.

Just using proper function declares should be enough.

This is exactly what I can't find.

Perhaps you could point me to a how-to guide?

This is exactly what I can't find.

Perhaps you could point me to a how-to guide?

Don't know if this is what you are looking for, but I've written quite a few tutorials on issues relating to inter-operating between C/C++ and PowerBASIC here...

http://www.jose.it-berater.org/smfforum/index.php?board=380.0

Starting in around Program Examples 11 through 19 I give quite a few examples of calling dlls created in PowerBASIC and loading them in C++ and vice-versa; also parameter passing issues, etc. Some of it would relate to VB.NET I expect. I cover LoadLibrary() and GetProcAddress() there.

If you would post a function and any structs necessary here, I'd take a look at it tomorrow some time.

Well in VB6, I would use

Declare Function ProcessTrans Lib "MaxTran2.dll" (ByVal ObjectHandle As Long, XTrans As MAXTransItem) As Long

to create the function locally and then use

retCode = ProcessTrans(MaxTransHandle,TransStruct)

to call it directly.

Is there an equivalent in C++?


I've found the solution to my third party dll by creating a VB6 dll but am still curious for the answer.

This would be my guess...

#include <stdio.h>

struct MAXTransItem   //you need to define this...
{
 .....
 .....
 .....

};


__declspec(dllimport) int __stdcall ProcessTrans(int, MAXTransItem&);  


int main(void)
{
 MAXTransItem mti;
 int hObject;
 int iReturn;

 hObject = ????;  //fill in
 iReturn=ProcessTrans(hObject,XTrans);
 printf("iReturn = %d\n", iReturn);
 getchar();

 return 0;
}

...and the dll itself would need to be somewhere in the dll search path, such as the directiory from which the exe is executing.

Note that by appending the '&' symbol (C/C++ address of operator) to MAXTransItem, i.e., MAXTransItem&, you are stating that the address of the struct is being passed to the ProcessTrans() function, and this corresponds to BASIC pass by reference. Such a construct requires C++ compilation and will throw a compile error if C copilation is used. For C you would declare MAXTransItem* instead.

Just occurred to me you'll probably need a LoadLibrary("PathToDll") call there too. Of course, in basic dialects that's included in the declare. The dllimport statement should make unnecessary a GetProcAddress() call.

I just put together an actual pair of C++ projects using your struct description and function signature and have it working. To load the dll you need to go into your project settings and link to the export library created by the dll creation process (that is, if you want to avoid LoadLibrary() / GetProcAddress()). Anyway, I named the dll 'CppDll.dll' and the host project 'dllHost.exe'. Here is the code for CppDll.dll...

//dllMain.cpp
/*
  Project CppDll  -- Compile as Dll


*/
#include <string.h>

struct MAXTransItem   //whatever...
{
 int     iItemNumber;
 char    szItemDescription[36];
 double  dblCost;
};

extern "C" __declspec(dllexport) int __stdcall ProcessTrans(int, MAXTransItem&);


int __stdcall ProcessTrans(int iQuantity, MAXTransItem& mti)
{
 mti.iItemNumber=37;
 strcpy(mti.szItemDescription,"Genuine Ash Axe Handles");
 mti.dblCost=iQuantity*6.95;

 return true;
}

And here is the code for the host app that loads the dll. The output follows directly after...

/*
  Project -- dllHost

  Main.cpp  In whatever C++ development environment you are using, you must
  link this executable with the CppDll.dll export library which contains the
  symbols exported from the dll.  Generally, there is some sort of option
  under Project Properties >> Build Options to set paths to export libraries.
  With Microsoft compilers these have an extension of .lib.  With GNU compilers
  the extension is *.a.  With Dev-Cpp or CodeBlocks, if the .a file is in the
  same directory as the host executable, specify the full path to the export
  library rather than a relative path.  The relative path will probably only
  work if the export library is in the \lib folder of the compilers directory.
*/
#include <stdio.h>

struct MAXTransItem   //whatever...
{
 int     iItemNumber;
 char    szItemDescription[36];
 double  dblCost;
};

extern "C" __declspec(dllimport) int __stdcall ProcessTrans(int, MAXTransItem&);


int main(void)
{
 MAXTransItem mti;

 if(ProcessTrans(5,mti))
 {
    printf("mti.iItemNumber        = %d\n",mti.iItemNumber);
    printf("mti.szItemDescription  = %s\n",mti.szItemDescription);
    printf("mti.dblCost            = %6.2f\n",mti.dblCost);
 }
 else
   puts("ProcessTrans() Failed Abysimally!  You're Out Of Luck.");

 getchar();

 return 0;
}

/*
Output
================================================
mti.iItemNumber        = 37
mti.szItemDescription  = Genuine Ash Axe Handles
mti.dblCost            = 34.75
*/

I'm working on a PInvoke VB.NET implementation that loads this C++ dll. Will have it ready shortly (maybe tomorrow).

Just occurred to me you'll probably need a LoadLibrary("PathToDll") call there too.

\

That is only necessary if you want to use GetProcAddress(). The Windows OS program loader will auto load the dll when it starts the program.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.