0
votes

I am following the guide on: https://msdn.microsoft.com/en-us/library/ms235636.aspx

I have created a DLL as it was stated above and now i want to include it in my VB6 app

I have declared a function in the code:

Private Declare Function Add Lib "C:\WINDOWS\system32\Win32Project1.dll" (ByVal a As Double, ByVal b As Double)

In the form load I have declared some variables and called a function

Dim a As Double
Dim b As Integer

a = 7.4
b = 99

Call Add(a, b)

Each time I run program I get an error that file not found. File is present in C:\WINDOWS\system32\ and I did try to register dll using:

regsvr32 Win32Project1.dll

But I keep getting error: LoadLibrary("Win32Project1.dll") failed - The specified module could not be found.

How can this be resolved?


Update: I have looked further into the issue, please refer to step 2 of "Martin Schlott" answer, and it happens that VC++ encodes DLL functions and because of that i would have a funny name of ever function within DLL.

Using dumpbin.exe, which can be found in the $\Visual Studio\VC\bin, i was able to read the function names that are stored in the DLL. This is what I would get originally:

      1    0 00001050 ?Add@MyMathFuncs@MathFuncs@@SANNN@Z = ?Add@MyMathFuncs

@MathFuncs@@SANNN@Z (public: static double __cdecl MathFuncs::MyMathFuncs::Add(d ouble,double))

"?Add@MyMathFuncs@MathFuncs@@SANNN@Z" - is what I would have to call as a function in VB6 for things to work... and it wouldn't... so I had to decode the name which is done by creating a definition file (.def) within C++ DLL app

In the new Source.def file I have defined that I want to have "Add" function:

     LIBRARY 

     EXPORTS
        Add

After rebuilding solution in the "Release" mode dumpbin gave me a much better result. However, __cdecl is automatically added to every function in VC++, unless specified otherways, and it happens that __cdecl doesn't allow function to be used in the VB6. If you run VB6 app right now you would receive a new error "Bad DLL calling convention".

For this to be resolved I had to amend "MyMathFuncs.h" file where I have defined functions to export and change

     "static MATHFUNCSDLL_API double Add(double a, double b);"

to

     "static MATHFUNCSDLL_API double __stdcall Add(double a, double b);"

After that dumpbin.exe returned much nicer values:

     1    3 00001050 Add

This however haven't resolved my problem fully, I would still get "Bad DLL calling convention" and it was due to how I have referenced library in the VB6

     Private Declare Function Add Lib "Win32Project1.dll" (ByVal a As Double, ByVal b As Double)

The function "Add" returns a double and in the abovee declaration I declare that values should be pushed and no return given. So I have followed the function format that I have in C++ and added a return with a correct data type that matches the data type in C++ file:

     Private Declare Function Add Lib "Win32Project1.dll" (ByVal a As Double, ByVal b As Double) As Double

Now when I run:

Dim a As Double
Dim b As Integer

a = 7.4
b = 99

MsgBox (Add(a, b))

I have a message box stating that result is 106.4!

1
I have used program "Dependency Walker" and found that I am missing MSVCR120D.DLLVlad Vladimir Hercules
The advice in this question and its accepted answer might be useful if you're still having problems stackoverflow.com/questions/14281368/…MarkJ

1 Answers

1
votes

There are several points wrong in that what you are doing. Funny thing is,nevertheless it should work.

If you specify a DLL directly, you do not need to register it with regsvr32.

Read: https://msdn.microsoft.com/en-us/library/aa716201(v=vs.60).aspx

resvr32 expect special exported functions to COM Conform register the DLL in the registry. A COM able DLL can be used via for e.g. with CoCreateInstance not with your declare.

If you didn't know this, regsvr is failing.

Also do not copy DLL belonging to your Project into the system32 folder. It do not belong there and it is bad behavior nowadays. For disk memory reasons it was maybe necessary centuries ago, but not today.

Copy the DLL in the same folder where the VB program is. Correct the path to

Private Declare Function Add Lib "Win32Project1.dll" (ByVal a As Double, ByVal b As Double)

and as someone already suggest, use dependency walker. If a dll starting with "MS" is missing. Read my following answer:

https://stackoverflow.com/a/18600033/1922748

to install the proper redist.

UPDATE

You wrote you are missing the "MSVCR120D.DLL". This happens if you compiled the DLL in debug mode, not release mode. You cannot install the MSVCR120D.DLL without the Visual Studio. You need to compile your DLL in release mode and install the redist.

2. Second Update

Regarding to your last comment, the entry point is missing. You have to export the function! Add

__declspec(dllexport) 

before the function you want to export. Look here https://msdn.microsoft.com/de-de/library/3y1sfaz2.aspx

Your declaration in C++ should look like:

__declspec(dllexport) double Add(double val);

You can forget about dllimport, you do not need that in your case.