1

This is a follow-up question to this question because I'm losing my mind over this right now.

Someone pointed me to this article and I'm trying to copy section 4 from there.

So I created an empty C++ Project in MSVC++2010, created a new .cpp file inside it, and put the following code in there:

#include <windows.h>
#define CCONV _declspec(dllexport) // used to be __stdcall but resulting DLL is identical

int CALLBACK LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
LPSTR lpszCmdLine)
{
     return 1;
}

short CCONV PassInteger (short intgr, short far *pintgr)
{
    *pintgr = intgr;
    return intgr + 1;
}

(I got the LibMain code from here but I think it doesn't do anything here.)

Then, I added a .def file to the project and put this in it:

;vb6dll32 DEF File
LIBRARY vb6dll32

CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE

EXPORTS
PassInteger

The compiler outputs two warnings that CODE and DATA in the .def file are not supported for the current target, but it eventually compiles and generates the file vb6dll32.dll which I have then copied to C:\windows\system and ...\system32 and C:\.

Then I have created a VB6 project, put a button into the form and added this sourcecode:

Private Declare Function PassInteger Lib "vb6dll32.dll" _
(ByVal intgr As Integer, pintgr As Integer) As Integer

Private Function BuiltIntest() As Integer

    Dim i As Integer
    Dim ir As Integer

    i = 7

    i = PassInteger(i, ir)
    Print i, ir

    Return

End Function

Private Sub Command1_Click()
    MsgBox (BuiltIntest())
End Sub

Now, when I click the button, it still gives me "Runtime error '53': file vb6dll32.dll not found." (This happens even if I give it a fully specified path in the VB source code, e.g. "C:\vb6dll32.dll" and the file is definitely there. I tried giving its location without path and without ".dll" and so on, nothing changes.)

What also bugs me is, when I run regsvr32 c:\vb6dll32.dll it also tells me "The module C:\vb6dll32.dll could not be loaded. etc etc" .. I have no idea what it should do but that should generally do something for DLL files, right?

What am I doing wrong?! Thanks for your help.

Community
  • 1
  • 1
Felix Dombek
  • 13,664
  • 17
  • 79
  • 131

3 Answers3

4

In your examples (code and regsvr32 call), you are referring to c:\vb6dll32.dll. But you said you copied it to the system32 directory. The path you specified would require that it be in the root. Since you copied it to the system32 directory, it should work without any path. Try removing the c:\ from the name.

Edit Since I'm striking out on all fronts, you might be hesitant to follow my advice ... but Dependency Walker may help solve this. It could be that a DLL needed by your DLL is not being found (e.g., one of the CRT DLLs). That depends.exe utility is a very useful tool and will show if any necessary DLLs are missing.

Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
  • It doesn't matter. I tried it without path, without ".dll", with path, copied it to "C:\", tried that path ... nothing changes. – Felix Dombek Feb 14 '11 at 14:23
  • I'm not sure if this is applicable given the error message, but you might try running the command `dumpbin /exports vb6dll32.dll`. If it is a valid DLL, then you should see the exported symbol. The dumpbin.exe command should be in the vc\bin directory under your visual studio install. There should also be a batch file named something like vcvars32.bat that will set your path variable to reach that utility. – Mark Wilkins Feb 14 '11 at 14:33
  • That certainly seems suspicious and makes it sound like the visual studio install has a problem. I really don't know, though, if it would be directly related to the inability to load the DLL. – Mark Wilkins Feb 14 '11 at 14:49
  • Thanks a lot. Dumpbin finds the exports and lists all exported functions -- correctly, as far as I can see that. (Sorry for the previous post. I had forgotten to prepare the console with vcvars32 first.) – Felix Dombek Feb 14 '11 at 14:49
  • @Felix: No problem about that. I added a note about depends.exe that you might look into (if you want to keep following my advice that hasn't helped yet :) – Mark Wilkins Feb 14 '11 at 15:19
3

Maybe your vb6dll32.dll is dynamically linked and depends on stuff like MSVCR100.dll, which isn't easy to locate. Check imports and put these dlls beside your vb6dll32.dll, or link it statically (/MT /LD).
Also you really don't need these CODE and DATA lines in the .def file.

Shelwien
  • 2,160
  • 15
  • 17
  • Actually, you seem to be quite right. I used Dependency Walker as proposed by Mark and it says that my DLL depends on two other things: KERNEL32.DLL and MSVCR100.DLL, which isn't found. How do I solve this? – Felix Dombek Feb 14 '11 at 15:42
  • 1
    Link with (/MT) instead of (/MD) in your c++ project properties goto "Configuration Properties > C/C++ > Code Generation > Runtime Library". This will statically include MSVCR100, which will make your DLL larger but you wont have to worry about the dependency – Tom Fobear Feb 14 '11 at 15:44
1

LibMain is from 16bit windows. You should use DllMain. http://msdn.microsoft.com/en-us/library/ms682583(v=vs.85).aspx. You can look at fdwReason against DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH for when the dll is loaded and unloaded with LoadLibrary. There are some stipulations to what you can use in DllMain, for example no unmanaged code.

Tom Fobear
  • 6,729
  • 7
  • 42
  • 74
  • I can use no unmanaged code in DllMain? It's probably the other way around, isn't it? – Felix Dombek Feb 14 '11 at 14:26
  • @Felix Dombek: You are correct, I meant managed. The reason is you cannot call LoadLibrary in DllMain (look a little more than half way down msdn article). Because managed code may load external libraries at any time, you cannot make managed calls. I apologize if you already knew this but it might help related problems. – Tom Fobear Feb 14 '11 at 14:43
  • No, I didn't know that, thanks. However, I'm not intending to use managed code here. I just want to have a minimal test case of a C++ DLL with exports. – Felix Dombek Feb 14 '11 at 14:45