When I create a DLL and I wish to export functions, I can choose between
creating .def file for functions I wish to export, or use
__declspec(dllexport).
What is the difference?
Here are 3 methods tried and under which name they were exported:
.def :
MyFunc
.def with extern "C"
MyFunc
__declspec(dllexport)
?MyFunc@YGHPB...
__declspec(dllexport) with extern "C"
_MyFunc@16
I understand why there is name mangling for C++ (allow export of overloaded
functions and such, right?)
But not the difference between .def and __declspec(dllexport)
.. or more particularly, why the latter does not give same result as extern
"C", but "_ ... @N" format instead?
Lisa
By default, MSVC uses __cdecl for C and C++.
http://msdn.microsoft.com/en-us/library/984x0h58.aspx
gg
In addition, if you want both __stdcall calling convention and no
declaration (e.g. just 'MyFunc' with __stdcall and extern "C"), the only
option you have is to use .def files.
For all other cases, I would suggest using __declspec.
Giovanni
I still don't understand why extern "C" with __declspec(dllexport) exports
function as "_ Func @ N" instead of just "Func" that I get when exporting
with .def file.
Lisa
"Codeplug" <Code...@nospam.invalid> wrote in message
news:dlWol.16295$FI5....@newsfe07.iad...
Historically .DEF files precede __declspec(dllexport) specifier. A
function which is exported via .DEF file will be stripped of any
name decoration (be it C or C++ decoration). Long time ago .DEF
files were the only way to export functions and data. People used
to write the same name of a fuction in a .DEF file as it appeared
in C code regardless of calling convention.
When __declspec(dllexport) specifier emerged, then each calling
convention got its own name decoration scheme. Both C and C++
functions get decorated when exported. The difference is that
there is an agreement between compiler vendors about C decoration
scheemes, while C++ decoration is specific to each vendor, thus
incompatible between different compilers.
Alex
So for compatibility, it's recommended to use .def?
Is there any advantage to using __declspec(dllexport) with extern "C" ?
Lisa
"Alex Blekhman" <tkfx....@yahoo.com> wrote in message
news:O29mQm1l...@TK2MSFTNGP06.phx.gbl...
The calling convention is coded into the exported symbol, so mismatches will
be caught at link time.
Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
> I still don't understand why extern "C" with __declspec(dllexport) exports
> function as "_ Func @ N" instead of just "Func" that I get when exporting
> with .def file.
Keep in mind that both the "linkage" and the "calling convention" can
affect the "decoration" of a symbol:
extern "C" __stdcall will give you "_Func@N"
extern "C" __cdecl will give you "Func", just like .def
> Thank you for wonderful explanation.
> So this confirms .def is not identical to export "C" with
> __declspec(dllexport).
It is when it's __cdecl.
> So for compatibility, it's recommended to use .def?
"Compatibility" depends on the who the clients of the DLL are and what
they expect.
> Is there any advantage to using __declspec(dllexport) with extern "C" ?
The advantage is not having to write and maintain a .def file :)
gg
no, it will give you "_Func". The only way to prevent any decoration is
with the .def file.
gg
Just tested it myself (again) with Visual Studio 2005 SP1.
extern "C" __declspec(dllexport) int __cdecl Test( double ) { return 0; }
turns into (ran dumpbin on the generated import library):
File Type: LIBRARY
Exports
ordinal name
_Test
and dumpbin on the DLL itself:
ordinal hint RVA name
4 0 00001160 Test = _Test
The underscore is clearly present.
I'd advise showing an actual example, not referencing documentation that
doesn't even address the question at hand, when contradicting an MVP.
Otherwise you just end up making yourself look bad when it turns out they
were right after all.
I understand your point (in this case), but be careful, MVPs not always are
right...
> Otherwise you just end up making yourself look bad when it turns
> out they were right after all.
--
Cholo Lennon
Bs.As.
ARG
There's no point at looking at the import library to see what a DLL
exports - when you can just look at the DLL.
> and dumpbin on the DLL itself:
>
> ordinal hint RVA name
>
> 4 0 00001160 Test = _Test
>
>
> The underscore is clearly present.
"Test" is also clearly present (and listed first). Use depends.exe if
you like. You will see "Test" as the exported symbol name. Use
GetProcAddress() if you like, you will need to pass in "Test".
> I'd advise showing an actual example, not referencing documentation that
> doesn't even address the question at hand, when contradicting an MVP.
[Quote:]
[__cdecl] name-decoration convention -
Underscore character (_) is prefixed to names, *except when exporting
__cdecl functions that use C linkage*.
[End Quote]
Doesn't that address our disagreement directly?
> Otherwise you just end up making yourself look bad when it turns out they
> were right after all.
Indeed!
BTW, I'd love to know the results of your dumpbin test when using a .def
file for Test().
gg
That was a bit petty of me. The point was that you get the same results
either way.
Back to the original disagreement:
> no, it will give you "_Func". The only way to prevent any decoration is
> with the .def file.
By comparing the dumpbin results between using .def and using extern "C"
__cdecl - you will see no differences. Therefore, either method works
equally well to achieve the same result.
gg
Well no, this refers to functions exported from the compile unit (i.e.
non-static linkage, not in the anonymous namespace). It most definitely
affects linking together .obj files and .lib files when no DLLs are in use
whatsoever.
__declspec(dllexport) is a different beast not directly addressed by the
documentation you cited.
Moreover, the documentation appears to be wrong. The generated object files
(and error messages concerning undefined externals) do have an underscore
(speaking from experience, not a new bout of testing).
[snip]
The use of the term "exporting" in the quoted documentation obviously
does not refer to _external_ symbols in a compilation unit...the dumpbin
tests verified that much. Of course, external symbol names in object
file have little or nothing to do with this thread...
> __declspec(dllexport) is a different beast not directly addressed by the
> documentation you cited.
>
> Moreover, the documentation appears to be wrong. The generated object files
> (and error messages concerning undefined externals) do have an underscore
> (speaking from experience, not a new bout of testing).
The docs are correct, despite incorrect interpretations. One could
suggest a clarification such as: "except when exporting from Dll's" -
but that seems redundant to me - what else would you be "exporting" from?
gg
>The docs are correct, despite incorrect interpretations. One could
>suggest a clarification such as: "except when exporting from Dll's" -
>but that seems redundant to me - what else would you be "exporting" from?
It's unusual, but EXEs can export functions, and DLLs loaded into their
processes can GetProcAddress them. The kernel EXEs export a bunch of
functions, e.g. try:
dumpbin /exports ntkrnlpa.exe
--
Doug Harrison
Visual C++ MVP
"export" is a C++ keyword, didn'tcha know. And it has absolutely nothing to
do with DLLs. Of course, that's not how Microsoft is using the word here,
but still.
>
> gg
>Thank you for wonderful explanation.
>So this confirms .def is not identical to export "C" with
>__declspec(dllexport).
>
>So for compatibility, it's recommended to use .def?
>Is there any advantage to using __declspec(dllexport) with extern "C" ?
There's another way to do this without using a .def file. You can say:
#pragma comment( linker, "/export:_MyFunc" )
extern "C"
void MyFunc( ... )
I like this, because it keeps all the knowledge about the function in one
spot.
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.