Hello everyone,


I think extern C is enough to prevent name from decorated, but when we
export function names from a DLL using dllexport, even if we declare at the
same time with extern C, but without a DEF file to define un-decorated
exported function names, the name is still decorated.

I do not know why DEF file is needed? extern C is not enough to control name
decoration for both DLL exported names and current DLL model linking?


regards,
George

Re: name decoration issue in DLL by Igor

Igor
Sun Oct 05 07:45:43 CDT 2008

"George" <George@discussions.microsoft.com> wrote in message
news:34A5288E-A619-4132-9A1E-8EF7B08B5BE4@microsoft.com
> I think extern C is enough to prevent name from decorated, but when we
> export function names from a DLL using dllexport, even if we declare
> at the same time with extern C, but without a DEF file to define
> un-decorated exported function names, the name is still decorated.

There are two mechanisms in play here: C++ name mangling, and C name
decoration. Name mangling encodes function signature (parameter and
return types) into exported name, which allows overloaded functions to
have distinct names for linkage purposes. Name decoration depends only
on the function's calling convention; e.g. __stdcall functions normally
get exported as _FunctionName@XX (where XX is the total size of
parameters).

extern "C" suppresses name mangling, but not name decoration. To
suppress the latter, one must use DEF file.

> I do not know why DEF file is needed? extern C is not enough to
> control name decoration for both DLL exported names and current DLL
> model linking?

Obviously not, or you wouldn't be here asking this question.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: name decoration issue in DLL by George

George
Sun Oct 05 07:55:01 CDT 2008

Thanks Igor!


Your reply is excellent. I have tried but have different results from well
documented rules of MSDN.

In the document,

http://msdn.microsoft.com/en-us/library/x7kb4e2f.aspx

it is mentioned default calling convention is __cdecl, and the resulting
name in DLL should begin with sign _.

But my result is the default calling convention __cdecl results in name
without _ sign? Here is my code and my output. Any ideas?

I am using VS 2008, Debug build for Win32.

D:\Visual Studio 2008\Projects\TestDll2\Debug>dumpbin /exports TestDll2.dll
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file TestDll2.dll

File Type: DLL

Section contains the following exports for TestDll2.dll

00000000 characteristics
48E8B6E6 time date stamp Sun Oct 05 20:45:26 2008
0.00 version
1 ordinal base
2 number of functions
2 number of names

ordinal hint RVA name

1 0 000110AF MyFunc1 = @ILT+170(_MyFunc1)
2 1 0001106E _MyFunc2@4 = @ILT+105(_MyFunc2@4)

Summary

1000 .data
1000 .idata
2000 .rdata
1000 .reloc
1000 .rsrc
4000 .text
10000 .textbss




extern "C"
{
__declspec (dllexport) int MyFunc1 (int A) {return 100;}
__declspec (dllexport) int __stdcall MyFunc2 (int A) {return 100;}
}


regards,
George

Re: name decoration issue in DLL by George

George
Mon Oct 06 06:26:10 CDT 2008

Hi Igor,


I did some research today and find it is maybe under __cdecl mode, compiler
removes the _ leading sign of function symbol name. And it seems a bug of the
MSDN page, which said __cdecl names begins with _ sign?

http://msdn.microsoft.com/en-us/library/x7kb4e2f.aspx

But I am not 100% sure about it. It is appreciated if you could share some
ideas.


regards,
George

Re: name decoration issue in DLL by Norbert

Norbert
Mon Oct 06 12:45:43 CDT 2008


George schrieb:

> I did some research today and find it is maybe under __cdecl mode, compiler
> removes the _ leading sign of function symbol name. And it seems a bug of the
> MSDN page, which said __cdecl names begins with _ sign?

No you are wrong. The compiler does decorate the function name with the "_"
sign. Nevertheless, you do not need a DEF file.

The following DLL:

extern "C"
__declspec(dllexport) int __stdcall ExportStdcall(int a)
{
return 3;
}

extern "C"
__declspec(dllexport) int __cdecl ExportCdecl(int a)
{
return 4;
}


produces the follwing entries in the export table:

Exports

ordinal name

1 _ExportCdecl
exported name: ExportCdecl
2 _ExportStdcall@4

So the compiler actually adds and preserves the "_" sign, but the linker adds
the undecorated name to the DLL's export table and so makes it available to
GetProcAddress.

Norbert

Re: name decoration issue in DLL by Norbert

Norbert
Mon Oct 06 12:49:12 CDT 2008



Igor Tandetnik schrieb:

> extern "C" suppresses name mangling, but not name decoration. To
> suppress the latter, one must use DEF file.

Wrong. I did not need a DEF file since __declspec(dllexport).
__declspec(dllexport) on __cdecl functions automatically adds the undecorated
function name to the export table.

Norbert

Re: name decoration issue in DLL by Igor

Igor
Mon Oct 06 18:20:07 CDT 2008

Norbert Unterberg <nunterberg@newsgroups.nospam> wrote:
> Igor Tandetnik schrieb:
>
>> extern "C" suppresses name mangling, but not name decoration. To
>> suppress the latter, one must use DEF file.
>
> Wrong. I did not need a DEF file since __declspec(dllexport).
> __declspec(dllexport) on __cdecl functions automatically adds the
> undecorated function name to the export table.

Most of the time, you would want to export __stdcall functions though.
Otherwise your DLL cannot be consumed from, say, VB.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: name decoration issue in DLL by George

George
Tue Oct 07 01:44:00 CDT 2008

Thanks Igor,


I agree.


regards,
George

Re: name decoration issue in DLL by George

George
Tue Oct 07 01:48:00 CDT 2008

Thanks Norbert,


I agree. I think extern C only make C++ name mangling to C name mangling,
and it never controls DLL exported function name -- DEF is used to control it.

If not using DEF file, internal name, either C decoration style or C++
decoration style will be used as names exported from DLL.

Are they correct understanding?


regards,
George

Re: name decoration issue in DLL by George

George
Tue Oct 07 01:50:01 CDT 2008

Thanks Norbert,


> Exports
>
> ordinal name
>
> 1 _ExportCdecl
> exported name: ExportCdecl
> 2 _ExportStdcall@4

Where do you get the export table? From dumpbin /exports?


regards,
George

Re: name decoration issue in DLL by Norbert

Norbert
Tue Oct 07 06:24:29 CDT 2008

George schrieb:
> Thanks Norbert,
>
>
>> Exports
>>
>> ordinal name
>>
>> 1 _ExportCdecl
>> exported name: ExportCdecl
>> 2 _ExportStdcall@4
>
> Where do you get the export table? From dumpbin /exports?

That's from the map file.

Re: name decoration issue in DLL by George

George
Wed Oct 08 02:58:00 CDT 2008

Thanks Norbert,


Here is the content of the source file of the dll, maindll.cpp and my map
file content, it does not contain information about an export section as you
mentioned before.

Anything wrong with my environment? I am using VC 2008.

--------------------
maindll.cpp

extern "C"
{
__declspec (dllexport) int MyFunc1 (int A) {return 100;}
__declspec (dllexport) int __stdcall MyFunc2 (int A) {return 100;}
}


TestDll2

Timestamp is 48ec66ca (Wed Oct 08 15:52:42 2008)

Preferred load address is 10000000

Start Length Name Class
0001:00000000 00010000H .textbss DATA
0002:00000000 000032ceH .text CODE
0003:00000000 00000104H .CRT$XCA DATA
0003:00000104 00000104H .CRT$XCZ DATA
0003:00000208 00000104H .CRT$XIA DATA
0003:0000030c 00000104H .CRT$XIAA DATA
0003:00000410 00000104H .CRT$XIZ DATA
0003:00000520 00000a26H .rdata DATA
0003:00000f48 00000163H .rdata$debug DATA
0003:000010ac 00000104H .rtc$IAA DATA
0003:000011b0 00000104H .rtc$IMZ DATA
0003:000012b4 00000104H .rtc$IZZ DATA
0003:000013b8 00000104H .rtc$TAA DATA
0003:000014bc 00000104H .rtc$TMZ DATA
0003:000015c0 00000104H .rtc$TZZ DATA
0003:000016c8 000001c2H .xdata$x DATA
0003:00001890 0000016eH .edata DATA
0004:00000000 00000133H .data DATA
0004:00000138 0000043cH .bss DATA
0005:00000000 00000028H .idata$2 DATA
0005:00000028 00000014H .idata$3 DATA
0005:0000003c 00000130H .idata$4 DATA
0005:0000016c 00000130H .idata$5 DATA
0005:0000029c 000004c5H .idata$6 DATA

Address Publics by Value Rva+Base Lib:Object

0000:00000000 ___safe_se_handler_table 00000000 <absolute>
0000:00000000 ___safe_se_handler_count 00000000 <absolute>
0000:00000000 ___ImageBase 10000000 <linker-defined>
0001:00000000 __enc$textbss$begin 10001000 <linker-defined>
0001:00010000 __enc$textbss$end 10011000 <linker-defined>
0002:00000310 _MyFunc1 10011310 f maindll.obj
0002:00000350 _MyFunc2@4 10011350 f maindll.obj
0002:00000390 __RTC_InitBase 10011390 f
MSVCRTD:_init_.obj
0002:000003d0 __RTC_Shutdown 100113d0 f
MSVCRTD:_init_.obj
0002:00000490 __CRT_INIT@12 10011490 f
MSVCRTD:crtdll.obj
0002:00000860 _NtCurrentTeb 10011860 f i
MSVCRTD:crtdll.obj
0002:00000870 __DllMainCRTStartup@12 10011870 f
MSVCRTD:crtdll.obj
0002:00000af0 __RTC_NumErrors 10011af0 f
MSVCRTD:_userapi_.obj
0002:00000b00 __RTC_GetErrDesc 10011b00 f
MSVCRTD:_userapi_.obj
0002:00000b20 __RTC_SetErrorType 10011b20 f
MSVCRTD:_userapi_.obj
0002:00000b50 __RTC_SetErrorFunc 10011b50 f
MSVCRTD:_userapi_.obj
0002:00000b80 __RTC_SetErrorFuncW 10011b80 f
MSVCRTD:_userapi_.obj
0002:00000bb0 ?_RTC_GetErrorFunc@@YAP6AHHPBDH00ZZPBX@Z 10011bb0 f
MSVCRTD:_userapi_.obj
0002:00000bc0 ?_RTC_GetErrorFuncW@@YAP6AHHPB_WH00ZZPBX@Z 10011bc0 f
MSVCRTD:_userapi_.obj
0002:00000bc6 __CRT_RTC_INITW 10011bc6 f
MSVCRTD:MSVCR90D.dll
0002:00000bd0 ___clean_type_info_names 10011bd0 f
MSVCRTD:tncleanup.obj
0002:00000bf0 __onexit 10011bf0 f
MSVCRTD:atonexit.obj
0002:00000d40 _atexit 10011d40 f
MSVCRTD:atonexit.obj
0002:00000d70 __RTC_Initialize 10011d70 f
MSVCRTD:_initsect_.obj
0002:00000da0 __RTC_Terminate 10011da0 f
MSVCRTD:_initsect_.obj
0002:00000dd0 __encode_pointer 10011dd0 f
MSVCRTD:MSVCR90D.dll
0002:00000dd6 __malloc_dbg 10011dd6 f
MSVCRTD:MSVCR90D.dll
0002:00000ddc __free_dbg 10011ddc f
MSVCRTD:MSVCR90D.dll
0002:00000de2 __encoded_null 10011de2 f
MSVCRTD:MSVCR90D.dll
0002:00000de8 __decode_pointer 10011de8 f
MSVCRTD:MSVCR90D.dll
0002:00000dee __CrtSetCheckCount 10011dee f
MSVCRTD:MSVCR90D.dll
0002:00000e00 __ValidateImageBase 10011e00 f
MSVCRTD:pesect.obj
0002:00000e80 __FindPESection 10011e80 f
MSVCRTD:pesect.obj
0002:00000f20 __IsNonwritableInCurrentImage 10011f20 f
MSVCRTD:pesect.obj
0002:00001076 __initterm 10012076 f
MSVCRTD:MSVCR90D.dll
0002:0000107c __initterm_e 1001207c f
MSVCRTD:MSVCR90D.dll
0002:00001082 __amsg_exit 10012082 f
MSVCRTD:MSVCR90D.dll
0002:00001090 ___security_init_cookie 10012090 f
MSVCRTD:gs_support.obj
0002:000011a2 ___CppXcptFilter 100121a2 f
MSVCRTD:MSVCR90D.dll
0002:000011b0 _DllMain@12 100121b0 f
MSVCRTD:dllmain.obj
0002:000011e0 __except_handler4 100121e0 f
MSVCRTD:chandler4gs.obj
0002:00001220 _DebuggerKnownHandle 10012220 f
MSVCRTD:_error_.obj
0002:00001300 ?_RTC_Failure@@YAXPAXH@Z 10012300 f
MSVCRTD:_error_.obj
0002:000016d0 ?_RTC_StackFailure@@YAXPAXPBD@Z 100126d0 f
MSVCRTD:_error_.obj
0002:00001810 ?_RTC_AllocaFailure@@YAXPAXPAU_RTC_ALLOCA_NODE@@H@Z
10012810 f MSVCRTD:_error_.obj
0002:00001a20 __RTC_UninitUse 10012a20 f
MSVCRTD:_error_.obj
0002:00001b44 ___clean_type_info_names_internal 10012b44 f
MSVCRTD:MSVCR90D.dll
0002:00001b4a __unlock 10012b4a f
MSVCRTD:MSVCR90D.dll
0002:00001b50 ___dllonexit 10012b50 f
MSVCRTD:MSVCR90D.dll
0002:00001b56 __lock 10012b56 f
MSVCRTD:MSVCR90D.dll
0002:00001b5c __except_handler4_common 10012b5c f
MSVCRTD:MSVCR90D.dll
0002:00001b70 @__security_check_cookie@4 10012b70 f
MSVCRTD:secchk.obj
0002:00001b90 ?_RTC_GetSrcLine@@YAHPAEPA_WKPAH1K@Z 10012b90 f
MSVCRTD:_pdblkup_.obj
0002:00002150 ___report_gsfailure 10013150 f
MSVCRTD:gs_report.obj
0002:000022a2 __crt_debugger_hook 100132a2 f
MSVCRTD:MSVCR90D.dll
0002:000022a8 _InterlockedExchange@8 100132a8 f
kernel32:KERNEL32.dll
0002:000022ae _Sleep@4 100132ae f
kernel32:KERNEL32.dll
0002:000022b4 _InterlockedCompareExchange@12 100132b4 f
kernel32:KERNEL32.dll
0002:000022ba _QueryPerformanceCounter@4 100132ba f
kernel32:KERNEL32.dll
0002:000022c0 _GetTickCount@0 100132c0 f
kernel32:KERNEL32.dll
0002:000022c6 _GetCurrentThreadId@0 100132c6 f
kernel32:KERNEL32.dll
0002:000022cc _GetCurrentProcessId@0 100132cc f
kernel32:KERNEL32.dll
0002:000022d2 _GetSystemTimeAsFileTime@4 100132d2 f
kernel32:KERNEL32.dll
0002:000022d8 _DisableThreadLibraryCalls@4 100132d8 f
kernel32:KERNEL32.dll
0002:000022de _IsDebuggerPresent@0 100132de f
kernel32:KERNEL32.dll
0002:000022e4 _RaiseException@16 100132e4 f
kernel32:KERNEL32.dll
0002:000022ea _DebugBreak@0 100132ea f
kernel32:KERNEL32.dll
0002:000022f0 _WideCharToMultiByte@32 100132f0 f
kernel32:KERNEL32.dll
0002:000022f6 _MultiByteToWideChar@24 100132f6 f
kernel32:KERNEL32.dll
0002:000022fc _lstrlenA@4 100132fc f
kernel32:KERNEL32.dll
0002:00002302 _GetProcAddress@8 10013302 f
kernel32:KERNEL32.dll
0002:00002308 _LoadLibraryA@4 10013308 f
kernel32:KERNEL32.dll
0002:0000230e _HeapFree@12 1001330e f
kernel32:KERNEL32.dll
0002:00002314 _HeapAlloc@12 10013314 f
kernel32:KERNEL32.dll
0002:0000231a _GetProcessHeap@0 1001331a f
kernel32:KERNEL32.dll
0002:00002320 _GetModuleFileNameW@12 10013320 f
kernel32:KERNEL32.dll
0002:00002326 _VirtualQuery@12 10013326 f
kernel32:KERNEL32.dll
0002:0000232c _FreeLibrary@4 1001332c f
kernel32:KERNEL32.dll
0002:00002332 _TerminateProcess@8 10013332 f
kernel32:KERNEL32.dll
0002:00002338 _GetCurrentProcess@0 10013338 f
kernel32:KERNEL32.dll
0002:0000233e _UnhandledExceptionFilter@4 1001333e f
kernel32:KERNEL32.dll
0002:00002344 _SetUnhandledExceptionFilter@4 10013344 f
kernel32:KERNEL32.dll
0003:00000000 ___xc_a 10015000
MSVCRTD:cinitexe.obj
0003:00000104 ___xc_z 10015104
MSVCRTD:cinitexe.obj
0003:00000208 ___xi_a 10015208
MSVCRTD:cinitexe.obj
0003:00000410 ___xi_z 10015410
MSVCRTD:cinitexe.obj
0003:0000053c __pRawDllMain 1001553c
MSVCRTD:crtdll.obj
0003:0000053c __pDefaultRawDllMain 1001553c
MSVCRTD:crtdll.obj
0003:00000540
??_C@_0DA@FJPPCPEH@f?3?2dd?2vctools?2crt_bld?2self_x86?2c@ 10015540
MSVCRTD:crtdll.obj
0003:0000057c
??_C@_0BP@OGBCLIBO@Stack?5around?5_alloca?5corrupted?$AA@ 1001557c
MSVCRTD:_userapi_.obj
0003:000005a4
??_C@_0CK@CNLNOEPB@Local?5variable?5used?5before?5initi@ 100155a4
MSVCRTD:_userapi_.obj
0003:000005d8 ??_C@_0BI@CIGMDCBH@Stack?5memory?5corruption?$AA@
100155d8 MSVCRTD:_userapi_.obj
0003:000005f4
??_C@_0CK@FEGOIOPB@Cast?5to?5smaller?5type?5causing?5los@ 100155f4
MSVCRTD:_userapi_.obj
0003:00000628 ??_C@_0BJ@HEGAHDFO@Stack?5pointer?5corruption?$AA@
10015628 MSVCRTD:_userapi_.obj
0003:00000660
?ProcessDetach@NativeDll@<CrtImplementationDetails>@@0IB 10015660
MSVCRTD:tncleanup.obj
0003:00000664
?ProcessAttach@NativeDll@<CrtImplementationDetails>@@0IB 10015664
MSVCRTD:tncleanup.obj
0003:00000668 ?ThreadAttach@NativeDll@<CrtImplementationDetails>@@0IB
10015668 MSVCRTD:tncleanup.obj
0003:0000066c ?ThreadDetach@NativeDll@<CrtImplementationDetails>@@0IB
1001566c MSVCRTD:tncleanup.obj
0003:00000670
?ProcessVerifier@NativeDll@<CrtImplementationDetails>@@0IB 10015670
MSVCRTD:tncleanup.obj
0003:00000674
??_C@_0BO@GNIAFIKK@Unknown?5Runtime?5Check?5Error?6?$AN?$AA@ 10015674
MSVCRTD:_error_.obj
000