Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VB is only capable of making COM Dlls - not quite true 2

Status
Not open for further replies.

mattKnight

Programmer
May 10, 2002
6,239
GB
thread222-1293630
Strongm said:
>VB is only capable of making COM Dlls

Not quite true (but probably not a subject we want to get into here ...)

Ok, I'll rise to the bait (and started a new thread...)

VB can create other types of object (so the only wasn't very precise)
Active-X Out of process (exe),
Active-X In process (Dll)
Normal Executable
Active-X Control (specifc type of DLL, OCX)
Plus some other more obscure things (MMC snap ins etc)

But I don't know how you can create, from VB, a windows Dll i.e. one that you use the include statement to use

So strongm the ball's in your court ;-)

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Well, here's an overview

1) You need to include a DLLMain entry point
2) You need to create a DEF file (because VB won't create the exports for you
3) You need to put in a shim to VB's LINK.EXE in order to insert a /DEF: option (that uses the DEF file you created in step 2) into it's command line

Job done
 
I would be interested to know if there is an advantage to creating a dll that is not a COM DLL.

-George

Strong and bitter words indicate a weak cause. - Fortune cookie wisdom
 
I leave that for the individual to decide ...

Anyway, here's the example: Firstly the DLL itself. Start a new ActiveX DLL project and add a module (I call mine VBDemo). Don't delete the default class, otherwise the project won't compile). Call the Project VBDLLDemo ...
Code:
[blue]Option Explicit

Public Const DLL_PROCESS_ATTACH = 1

' All 'classic' DLLs need this entry point, but we don't need to do too much in it
Public Function DllMain(hInst As Long, fdwReason As Long, lpvReserved As Long) As Boolean
   If fdwReason = DLL_PROCESS_ATTACH Then DllMain = True
End Function

Public Function VBDLLDemo(lSource As Long) As Long
    VBDLLDemo = lSource + 1
End Function[/blue]
Save it in it's own project folder (in my case the folder is called CLassicDLL). The drop in the following DEF file in that folder
Code:
[blue]NAME VBDLLDemo
LIBRARY VBDemo
DESCRIPTION "Example of classic DLL in VB"
EXPORTS DllMain @1
        VBDLLDemo @2[/blue]
Complicated so far, eh? Now comes the trickiest part (and it isn't really that tricky) - the shim. Start a new VB project, add a module and remove the default form. You'll also need to add references to Microsoft Scripting Runtime and the the VBScript Regular Expressions library. Here's the code:
Code:
[blue]Option Explicit

Public Sub Main()
    Dim strFolder As String
    Dim strDef As String
    Dim strCommand As String
    Dim fso As FileSystemObject
    
    strCommand = Command$
    Set fso = New FileSystemObject
    With New RegExp
        .Pattern = "(" & Chr$(34) & ")(" & ".*?OBJ" & ")(" & Chr(34) & ")"
        On Error Resume Next ' we'll get an error if there is no object file listed
            strFolder = fso.GetParentFolderName(.Execute(strCommand)(0).SubMatches(1))
        On Error GoTo 0
        strDef = Dir$(strFolder & "\*.DEF") 'look to see if there is a DEF file for this project
        If strDef <> "" Then 'if there is then modify the command line that will be passed to the original linker
            strCommand = Replace(strCommand, "/DLL", "/DEF:" & Chr(34) & strFolder & "\" & strDef & Chr(34) & " /DLL")
        End If
    End With
    Shell "OriginalVBLinker.exe " & strCommand ' call original linker with original or modified command line
End Sub[/blue]
Now compile the shim as, say, NewLinker.exe. Once done, rename the original LINK.EXE in your VB98 folder to OriginalVBLinker.exe, and then rename NewLinker.exe as LINK.EXE.

You can now compile the Active X DLL we originally created, and it will be compiled as a classic DLL. You can test iot with a program such as the following:
Code:
[blue]Option Explicit

Private Declare Function VBDLLDemo Lib "C:\Program Files\Microsoft Visual Studio\VB98\ClassicDLL\VBDLLDemo.DLL" (lSource As Long) As Long

Private Sub Command1_Click()
    MsgBox VBDLLDemo(5)
End Sub[/blue]

NOTE: this is an example of the technique, not robust production code.
 
OK, I'll digest and enjoy over the next couple of days...

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
Well, now I know I'll never accidentally create a classic DLL.

:)
 
:) By accident, no - but as I said in the example the only vaguely tricky bit is the shim (since we have to determine whether there is a DEF file in the project folder and if so to modify the command line parameters that VB has automatically generated and tried to kkep hiddn for us; and I resorted to some shortcuts to keep that code pretty short) - but you only need to create and compile the shim once.

And if you take the shim code out of the example you'll see there's hardly anything to it ...
 
just reading that trick made me proud ;)) Star for Strongm
 
I was convinced it could be done by your answer in the previous thread! I know only too well that you don't post a comment "Not quite true" without having the demonstration to back it up...

I must confess, that I still haven't had any time with a development platform to play, but I haven't forgotten

Take Care

Matt
If at first you don't succeed, skydiving is not for you.
 
I'm not quite sure what that adds. It is more-or-less exactly the same technique (which is hardly surprising, as I believe it is the only way of doing this) - and looks to me to be ultimately based on the same source article that I originally read (not the O'Reilly one that the link references, though)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top