EXP File Documentation
Summary
An .exp (export file) is a build artifact the Microsoft (MSVC) linker produces alongside an import library (.lib) when it builds a DLL that exports symbols. Its full name is Symbols Export File. The MIME type is application/octet-stream. It is an intermediate build file: it is safe to delete, the next build regenerates it, and you never open it by hand.
Technical details
| Full name | Export file (linker EXPORTS file) |
|---|---|
| File extension | .exp |
| MIME type | application/octet-stream |
| Format type | COFF export file / build artifact |
| Category | Developer files |
| Developer | Microsoft (MSVC toolchain) |
| Produced by | LIB.exe / LINK.exe when a DLL exports symbols |
| Paired with | .lib import library, .def module-definition file |
| Byte order | Little-endian (x86 / x64 PE-COFF) |
| Contains | Export directory: exported symbol names and ordinals (no code) |
| Human-readable | No (binary) |
| Magic number | None (COFF/archive object, not a signatured format) |
| Executable code | No |
| Typical location | Build output folders (Debug\, Release\) |
| Safe to delete | Yes (intermediate; regenerated on rebuild) |
| Related extensions | .lib .dll .def .obj .pdb |
| Specification | Using an Import Library and Export File (Microsoft Learn) |
What is an EXP (export) file?
An .exp file is an export file written by the Microsoft C/C++ (MSVC) linker. When the linker builds a DLL that exports symbols, it produces two companion files at the same time: an import library (.lib) that other projects link against, and this export file (.exp). The .exp is a byproduct of the build. It is not something you write, and it is not something you open in an editor. If you found a stray .exp in a Debug\ or Release\ folder and wondered what it was, this is it: leftover plumbing from compiling a DLL.
The file belongs to the PE/COFF world of Visual C++, the same ecosystem that produces object files (.obj), static and import libraries (.lib), and Windows DLLs and EXEs. It has been part of the MSVC toolchain for a long time, and the mechanism has not changed much: it exists so the linker can carry a DLL's export information from one build step to the next.
How the linker creates it: dllexport, .def and the import library
A DLL declares which functions and data it exposes in one of two ways. The first is in source code, by marking each symbol with __declspec(dllexport). The second is in a separate .def module-definition file, which lists the symbols under an EXPORTS section. Either way, the toolchain gathers that list of exported names.
When LINK.exe (or LIB.exe run with a .def) sees that a DLL exports symbols, it generates both the import library and the export file from that list:
.def + .obj --LIB / LINK--> .lib (import library) + .exp (export file)
.exp + .obj --LINK--------> .dll
A minimal .def file looks like this:
LIBRARY mathcore
EXPORTS
Add
Subtract
Multiply
The .lib is what consumers of the DLL link against so their calls resolve at load time. The .exp feeds back into the linker so it can build the .dll itself with the correct export table.
What the export file contains (COFF export directory)
Both the .lib and the .exp are in the COFF object and archive family, the same file family that LIB.exe and Unix ar manipulate. Inside the .exp is an export directory: the exported symbol names, their ordinals, and the relative virtual addresses (RVAs) the linker will wire up. That is all it holds. There is no executable code in an export file, and there is no distinctive ASCII header you can read. Because it is a COFF object rather than a signatured format, it has no reliable magic number of its own, and tools recognize it by its part in the build rather than by a byte pattern.
When you actually feed a .exp to the linker (circular DLL dependencies)
In an ordinary build you never mention the .exp on the command line. The linker creates it and consumes it on its own. There is one documented case where you pass it in by hand: when two modules import from each other. If DLL A calls into DLL B and DLL B calls back into DLL A, neither import library exists yet when you try to build the first module, so the symbols cannot resolve.
The fix is to break the cycle by building the import library first. You run LIB with the .def file to produce the .lib and the .exp without linking a full DLL:
LIB /DEF:mathcore.def /OUT:mathcore.lib
LINK mathcore.exp mathcore.obj /DLL /OUT:mathcore.dll
Now the other module can link against mathcore.lib, and when you finally build mathcore.dll you hand the already-generated mathcore.exp to LINK so its exports match the import library you published earlier. This is the scenario Microsoft describes under ".Exp Files as Linker Input."
Is it safe to delete?
Yes. The .exp is an intermediate build artifact. Deleting it does not affect a finished DLL, and it does not remove anything a running program needs. The next time you build the project, the linker writes a fresh one. You can exclude it from source control and clean it out of output folders without consequence. The only situation where you would keep one around is the circular-dependency workflow above, and even then it is regenerated whenever you rebuild the import library.
Other formats that use the .exp extension
The .exp extension is shared by unrelated formats. If your file is not a linker artifact, it may be one of these. Melco machine-embroidery uses .exp for stitch data, a design file opened by embroidery software such as Wilcom TrueSizer. The EXPRESS data-modeling language (ISO 10303-11, part of the STEP standard) also uses .exp for a plain-text schema file that begins with SCHEMA name;. Those are different formats that happen to share three letters. If your file opens as readable text starting with SCHEMA, or came out of an embroidery machine, it is not the export file described here.
References
- Microsoft Learn — .Exp Files as Linker Input
- Microsoft Learn — Using an Import Library and Export File
- Microsoft Learn — Exporting from a DLL Using DEF Files
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.