To get started, open your Visual Studio
for use with VC++. As depicted below, we'll start by
clicking
-
File
-
New
-
Project...
Step 2.
Now lets move on to naming our project and defining the project
type.
-
Select Win32
-
Win32 Project
-
Name of Project (this will result in easydll.dll)
-
OK
Step 3.
I know this is kind of redundant but I didnt want a premature
'Finish', so just click the 'Next' button.
Step 4.
-
DLL
-
Empty Project
-
Finish
Step 5.
This is what you should end up with.
A nice empty project.
Step 6.
-
Right click "Source Files"
-
Add
-
New Item...
Step 7.
-
Select "Visual C++"
-
C++ File (.cpp)
-
Name of project source file (could be anything)
-
Add
Step 8.
-
Right click "Source Files"
-
Add
-
New Item...
Step 9.
-
Select "Visual C++"
-
Text File (.txt)
-
Name of your file that contains a list of your dll functions
(could be anything)
-
Add
Step 10.
-
Select source file 'easydllsrc.cpp'
-
Type the header, #include <windows.h>
Step 11.
I could just give you the 'main' call function, but I want to teach
everyone how to find this for their future reference. In mIRC
type /Help or locate on file menu. Search for "DLL support"
scroll
down to "technical notes" and locate the routine...
int __stdcall procname(HWND mWnd,HWND aWnd, char *data, char *parms,
BOOL show, BOOL nopause)
Well done, now copy.
Step 12.
-
Select source file 'easydllsrc.cpp'
-
Paste
-
The routine appears
Step 13.
While still in 'easydllsrc.cpp' ...
-
Change 'procname' to the function name you want. In my case
"funk1"
-
Add left bracket to the routine
-
Add right bracket to the routine
-
Insert strcpy, sets the variable data="data"
-
Insert return 3; Sends it to mIRC.
Step 14.
-
Select exports.def
-
Type Library "easydllsrc" this must be your source file
name.
-
Type EXPORTS
-
Type funk1 @ 1
We use LIBRARY "easydllsrc" to link our function name list
to our source file. simple enough.
The funk1 @ 1
lets mIRC know the function exists and
that its the 1st function in the list.
Step 15.
The coding is complete, however we still have some
options to check over to ensure its success.
-
Right click 'easydll' project name.
-
Properties
Step 16.
I think this is where people get lost, or maybe just me not used
to
the snazzy interface.
-
Select C/C++
-
Precompiled Headers
-
Create/Use Precompiled header = Not using precompiled
headers
This messed me up alot, if you use precompiled headers, it'll require
stdafx.h
and you can even get it to work like this.. but if I understand it
right, its unnecessary
unless you have repitious compilng and may give you more of a
headache having it
enabled.
Step 17.
-
Select Linker
-
Select "Module Defenition File"
-
Add .\exports.def
-
OK
This was another headache that maybe others have, apparently
even though you did an Add, it might not associate it with
your
project... maybe I did something differently, I dont know but
it
was this that kept making mIRC say * $dll: no such routine
'function'
It wasnt until I did this step that it was abole to find my
routines.
Step 18.
Finally, this step is optional... until you start having problems, then
check
over this.
-
C/c++
-
Command-Line
-
Options
This is so you can check over your compiler options and find a
setting
that could be jamming up your works. It doesnt have to look exactly
like
this but if you have trouble, i'd try to get it as close as
possible.
Step 19.
-
Linker
-
Command-Line
-
Options
The same deal applies,
Step 20.
You should be able to compile by now, so go ahead and Build your
solution.
I include this only as a matter of efficiency and to show you how a
DLL might
look if you have multiple functions.
As you can see, the std_calling can be duplicated and only the
function name changes.
-
Select 'easydllsrc.cpp'
-
duplicate function
-
rename new function
Step 21.
This is a typical build output, its not the pretiest compile
as
you should probably change strcpy to strcpy_b or whatever,
but
its easy enough to figure out on your own. Hopefully this should
just
get you started.
Step 22.
I mentioned the matter of efficiency, I took the #define part from
another tuorial, basically
this just makes a macro called MircWire, so your functions don't
"appear" more complex.
1. Select 'easydllsrc.cpp'
1.5 #define MircWire(x)
2. change function to x
3 modify funk1 to MircWire(funk1)
4 modify funk2 to
MircWire(funk2)
Step 23.
As you've done before,
-
Add funk2 @ 2
-
Rebuild Solution
With any luck you're churning out DLLs in mIRC by now,
to access your accomplishments simply //echo -a :
$dll(path:\easydll.dll,funk1,a)
The path can be your VC++ Debug/Release directory, or you can copy it
to your mIRC
folder and avoid the path all together. For ease, you can copy
this here... //echo -a :: $dll($sfile(c:\),funk1,a)
The "a" parameter is actually being passed to your DLL
but
because we're not listening for it, nothing is done with it.
Step 24.
There is also another way to create a DLL function, avoiding using a
.DEF file all together.
so after you have a clean solution setup with your windows.h header
included you can try the
following:
extern "C" __declspec (dllexport) int __stdcall memmo (HWND mWnd, HWND
aWnd, char *data,
char *parms, BOOL show, BOOL nopause) {
strcpy(data,"data");
return 3;
}
Its the same as what we had before, except in front of our _stdcall we
put extern "C"
this changes the naming convention of our function to that of "C" and
not C++ which
would come out distorted. The __declspec (dllexport) is what brings out
our function name.
As you can see in the image, I have used a program called "DLL Export
Viewer", its been really
handy telling me what the function looks like.. and after a compile, if
I refresh and its not there
I can tell that the export was unsuccessful and i must be doing
something wrong.
You can download from here:
http://www.nirsoft.net/utils/dll_export_viewer.html
In the export viewer you will notice it says _memmo@24 , This is how
you will have to refer to it
in mIRC, rather than just by its plain routine name. Thats kind of the
cost you have to pay for not
making a defenition file, but personally I wouldnt mind skipping a few
steps in VC++ only to add
something like $+(_,name,@24) for mIRC. So do whats right for
you.
The reason why its like this is explained in http://wyw.dcweb.cn/stdcall.htm
(great tutorial btw), its
basically just a naming convention for stdcall which is what mIRC uses.
I tried to use _cdecl but mIRC
kept crashing with it.
I personally like this method better, because of how little code you
have to insert, and you won't have
to muck with the .def file. Note: if you do delete
your .def file, you will have to go into the properties
again and delete the .\exports.def you had inserted. For some reason
Visual Studio is not dealing with
the export files automatically, so keep that in mind.
This concludes Making a DLL for mIRC with Visual Studio 8.
by Chris Warren
Feel free to link to this tutorial, but please.. no
ripping.