Advertisement

Implimenting a DLL

Started by October 13, 2000 11:21 AM
11 comments, last by jt_845s 24 years, 3 months ago
A DLL is like a regular project: it has header files and source files, resources, whatever. You compile the DLL, and a library file (*.lib) is created if you have the /implib command line. All functions defined in a DLL header file have a __declspec(dllexport in their declaration:
int __declspec(dllexport) ThisFunc(); 


Outside the DLL, you have a header file. This file is seperate, but defines every function that''s in your DLL using __declspec(dllimport) instead:
int __declspec(dllimport) ThisFunc(); 


The __declspec tells the compiler to look through library files, and in turn those library files load the DLL for you.

I hope this helps. Its the way I did my DLL at least.
WhatEver:
Yes there should be an int in front of MyDLLFunction. So the correct line is DLLEXPORT int MyDLLFunction(). I was a little tired when i wrote it .

Anonymous Poster:
You dont have to use the __declspec(dllimport). If you link with the export library, and include the library header file, you can still use the functions in the DLL.

Lets say i have a DLL file and an export library, and the DLL contains a function called MyDLLFunction(). To use the function i just link with the export library and define the function in my game like this: int MyDLLFunction(), and everything works fine.

So why should i use __declspec(dllimport).

Advertisement
Actually, If you use __declspec(dllimport), the compiler compiles the declaration differently, and in the end you skip a level of indirection, which is faster.

Heres the quote from MSDN:

quote:
Using _declspec(dllimport) for Function Calls

In the following code example, assume func1 is a function that resides in a DLL separate from the .EXE file that contains the main function.

Without __declspec(dllimport), given this code:




void main(void)
{
func1();
}
the compiler generates code that looks like this:




call func1
and the linker translates the call into something like this:




call 0x4000000 ; The address of ''func1''.
If func1 exists in another DLL, the linker can''t resolve this directly because it has no way of knowing what the address of func1 is. In 16-bit environments, the linker adds this code address to a list in the .EXE that the loader would patch at run time with the correct address. In 32-bit environments, the linker generates a thunk of which it does know the address. The thunk looks like:




0x40000000: jmp DWORD PTR __imp_func1
Here __imp_func1 is the address for func1''s slot in the import address table of the .EXE file. All the addresses are thus known to the linker. The loader only has to update the .EXE file''s import address table at load time for everything to work correctly.

Therefore, using __declspec(dllimport) is better because if the linker does not generate a thunk if it is not required. Thunks make the code larger (on RISC systems, it can be several instructions) and can degrade your cache performance. If you tell the compiler the function is in a DLL, it can generate an indirect call for you.

So now this code:




__declspec(dllimport) void func1(void);
void main(void)
{
func1();
}
generates this instruction:




call DWORD PTR __imp_func1
There is no thunk and no jmp instruction, so the code is smaller and faster.

On the other hand, for function calls inside a DLL, you don''t want to have to use an indirect call. You already know a function''s address. Time and space is required to load and store the address of the function before an indirect call, so a direct call is always faster and smaller. You only want to use __declspec(dllimport) when calling DLL functions from the outside the DLL itself. Don''t use __declspec(dllimport) on functions inside a DLL when building that DLL.

This topic is closed to new replies.

Advertisement