Win32 API to enumerate dll export functions?
dumpbin /exports
is pretty much what you want, but that's a developer tool, not a Win32 API.
LoadLibraryEx
with DONT_RESOLVE_DLL_REFERENCES
is heavily cautioned against, but happens to be useful for this particular case – it does the heavy lifting of mapping the DLL into memory (but you don't actually need or want to use anything from the library), which makes it trivial for you to read the header: the module handle returned by LoadLibraryEx
points right at it.
#include <winnt.h>
HMODULE lib = LoadLibraryEx("library.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);
assert(((PIMAGE_DOS_HEADER)lib)->e_magic == IMAGE_DOS_SIGNATURE);
PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)((BYTE *)lib + ((PIMAGE_DOS_HEADER)lib)->e_lfanew);
assert(header->Signature == IMAGE_NT_SIGNATURE);
assert(header->OptionalHeader.NumberOfRvaAndSizes > 0);
PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE *)lib + header->
OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
assert(exports->AddressOfNames != 0);
BYTE** names = (BYTE**)((int)lib + exports->AddressOfNames);
for (int i = 0; i < exports->NumberOfNames; i++)
printf("Export: %s\n", (BYTE *)lib + (int)names[i]);
Totally untested, but I think it's more or less correct. (Famous last words.)
Listing the exported functions of a DLL
There is code here to do this. I have cleaned it up a bit and it worked in the scenario shown below, retrieving function names from Kernel32.Dll
.
#include "imagehlp.h"
void ListDLLFunctions(string sADllName, vector<string>& slListOfDllFunctions)
{
DWORD *dNameRVAs(0);
_IMAGE_EXPORT_DIRECTORY *ImageExportDirectory;
unsigned long cDirSize;
_LOADED_IMAGE LoadedImage;
string sName;
slListOfDllFunctions.clear();
if (MapAndLoad(sADllName.c_str(), NULL, &LoadedImage, TRUE, TRUE))
{
ImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)
ImageDirectoryEntryToData(LoadedImage.MappedAddress,
false, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);
if (ImageExportDirectory != NULL)
{
dNameRVAs = (DWORD *)ImageRvaToVa(LoadedImage.FileHeader,
LoadedImage.MappedAddress,
ImageExportDirectory->AddressOfNames, NULL);
for(size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)
{
sName = (char *)ImageRvaToVa(LoadedImage.FileHeader,
LoadedImage.MappedAddress,
dNameRVAs[i], NULL);
slListOfDllFunctions.push_back(sName);
}
}
UnMapAndLoad(&LoadedImage);
}
}
int main(int argc, char* argv[])
{
vector<string> names;
ListDLLFunctions("KERNEL32.DLL", names);
return 0;
}
Is there any native DLL export functions viewer?
you can use Dependency Walker to view the function name.
you can see the function's parameters only if it's decorated.
read the following from the FAQ:
How do I view the parameter and return types of a function?
For most functions, this information is simply not present in the module. The Windows' module file format only provides a single text string to identify each function. There is no structured way to list the number of parameters, the parameter types, or the return type. However, some languages do something called function "decoration" or "mangling", which is the process of encoding information into the text string. For example, a function like int Foo(int, int) encoded with simple decoration might be exported as _Foo@8. The 8 refers to the number of bytes used by the parameters. If C++ decoration is used, the function would be exported as ?Foo@@YGHHH@Z, which can be directly decoded back to the function's original prototype: int Foo(int, int). Dependency Walker supports C++ undecoration by using the Undecorate C++ Functions Command.
Exporting functions from a DLL with dllexport
If you want plain C exports, use a C project not C++. C++ DLLs rely on name-mangling for all the C++isms (namespaces etc...). You can compile your code as C by going into your project settings under C/C++->Advanced, there is an option "Compile As" which corresponds to the compiler switches /TP and /TC.
If you still want to use C++ to write the internals of your lib but export some functions unmangled for use outside C++, see the second section below.
Exporting/Importing DLL Libs in VC++
What you really want to do is define a conditional macro in a header that will be included in all of the source files in your DLL project:
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
Then on a function that you want to be exported you use LIBRARY_API
:
LIBRARY_API int GetCoolInteger();
In your library build project create a define LIBRARY_EXPORTS
this will cause your functions to be exported for your DLL build.
Since LIBRARY_EXPORTS
will not be defined in a project consuming the DLL, when that project includes the header file of your library all of the functions will be imported instead.
If your library is to be cross-platform you can define LIBRARY_API as nothing when not on Windows:
#ifdef _WIN32
# ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
# else
# define LIBRARY_API __declspec(dllimport)
# endif
#elif
# define LIBRARY_API
#endif
When using dllexport/dllimport you do not need to use DEF files, if you use DEF files you do not need to use dllexport/dllimport. The two methods accomplish the same task different ways, I believe that dllexport/dllimport is the recommended method out of the two.
Exporting unmangled functions from a C++ DLL for LoadLibrary/PInvoke
If you need this to use LoadLibrary and GetProcAddress, or maybe importing from another language (i.e PInvoke from .NET, or FFI in Python/R etc) you can use extern "C"
inline with your dllexport to tell the C++ compiler not to mangle the names. And since we are using GetProcAddress instead of dllimport we don't need to do the ifdef dance from above, just a simple dllexport:
The Code:
#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)
EXTERN_DLL_EXPORT int getEngineVersion() {
return 1;
}
EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
K.getGraphicsServer().addGraphicsDriver(
auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
);
}
And here's what the exports look like with Dumpbin /exports:
Dump of file opengl_plugin.dll
File Type: DLL
Section contains the following exports for opengl_plugin.dll
00000000 characteristics
49866068 time date stamp Sun Feb 01 19:54:32 2009
0.00 version
1 ordinal base
2 number of functions
2 number of names
ordinal hint RVA name
1 0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
2 1 00011028 registerPlugin = @ILT+35(_registerPlugin)
So this code works fine:
m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");
m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
::GetProcAddress(m_hDLL, "registerPlugin")
);
List non-.NET DLL functions from C#
After Remy Lebeau's comment pointed me in the right direction, I had a look for PE parsers and found PeNet. It does the job really well, and reveals plenty of information beyond just the exported functions.
It's on NuGet, so you can just install it, add using PeNet
to the top of the file, and then use code like this:
var pe = new PeFile(@"MyDll.dll");
var functions = pe.ExportedFunctions.Select(x => x.Name).ToList();
why the @number symbol at the end of an exported dll function
The "@n" is used by the stdcall
calling convention. You don't need to mention it in your declaration, you just need to change your declaration to stdcall
so that the compiler knows they need to be decorated with "@n" suffixes. Like this:
__declspec ( dllexport ) XLStatus __stdcall _xlActivateChannel(XLportHandle, XLuint64, unsigned int, unsigned int)
How to find out API functions of DLL files?
Unless the exported functions are something like a COM DLL or C++ with munging, the information simply isn't there to provide the arguments. It's normally possible to find the total size of the arguments, and there's a pretty decent chance that dividing by 4 will give something close to the right number, but beyond that it's down to manual labor, reading the assembly code to figure out how arguments are used.
If it's a COM DLL, it may include a type library that tells all about the contents of the DLL and how to use it. In this case, there will typically be only a very few exported functions to look at though -- you'll have to use COM to get at the real functionality.
If they're munged C++ names, then it'll depend on the compiler/toolset used to create the DLL. For example, if it was created with VC++, you can use UnDecorateSymbolName()
to get the full name and arguments.
Related Topics
How to Render Offscreen on Opengl
If (Cin ≫≫ X) - Why Can You Use That Condition
Best Way to Extract a Subvector from a Vector
Why Does C++11'S Lambda Require "Mutable" Keyword For Capture-By-Value, by Default
Why Does C++ Require a User-Provided Default Constructor to Default-Construct a Const Object
C/C++: Switch For Non-Integers
How Do C++ Class Members Get Initialized If I Don't Do It Explicitly
How to Pass Parameters Correctly
How to Initialize Base Class Member Variables in Derived Class Constructor
Unresolved External Symbol _Imp_Fprintf and _Imp_Iob_Func, Sdl2
How to Parse Space-Separated Floats in C++ Quickly
Rounding Up to the Nearest Multiple of a Number
How to Convert a Double into a String in C++
Std::String to Float or Double
Checking Cin Input Stream Produces an Integer
Read Numeric Data from a Text File in C++
Fastest Way to Get Ipv4 Address from String
Fastest Way to Determine If an Integer Is Between Two Integers (Inclusive) With Known Sets of Values