Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to export "DllCanUnloadNow" (prototypied in objbase.h) without .DEF file

463 views
Skip to first unread message

Mario Semo

unread,
Mar 13, 2008, 9:48:36 AM3/13/08
to
Hello,

This is not a windows api related question - even when my problems are based
on some windows standard (SDK) header files.

i want to export DllCanInloadNow (one of the COM-Server APIs) in my DLL.
The function is prototyped in objbase.h.
And this is the problem, the function is prototypied without any "export"
definition. So the question is : how to export this function without help of
external .DEF files.

Sample:

========= dll2.cpp =========
#include <windows.h>

#define X_Export __declspec(dllexport)


// BaseTyps.h
// #define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
// ObjBase.h
// STDAPI DllCanUnloadNow(void);

// 1st try
//X_Export STDAPI DllCanUnloadNow() -> error (invalid order of extern "C"
and linkage, ok!)

// 2nd try
EXTERN_C X_Export HRESULT STDAPICALLTYPE DllCanUnloadNow(void)
// dll2.cpp(13) : error C2375: 'DllCanUnloadNow' : redefinition; different
linkage
// C:\Programme\Microsoft SDKs\Windows\v6.0A\include\objbase.h(854) :
see declaration of 'DllCanUnloadNow'
{
return 0;
}
=================================

cl -W4 -nologo -D__WINDOWS__ /J /LD dll2.cpp

thx for any help.

mario.


Igor Tandetnik

unread,
Mar 13, 2008, 12:27:48 PM3/13/08
to
Mario Semo <mario...@Xhotmail.com> wrote:
> i want to export DllCanInloadNow (one of the COM-Server APIs) in my
> DLL. The function is prototyped in objbase.h.
> And this is the problem, the function is prototypied without any
> "export" definition. So the question is : how to export this function
> without help of external .DEF files.

You could use /EXPORT linker option, either specified in your project or
introduced in the source code via #pragma comment.
--
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


Mario Semo

unread,
Mar 13, 2008, 1:54:59 PM3/13/08
to
Igor,

>
> You could use /EXPORT linker option, either specified in your project or
> introduced in the source code via #pragma comment.

Ah, this is interesting.

So i tried:

STDAPI DllCanUnloadNow()
{
return 0;
}

#pragma comment(linker, "/EXPORT:DllCanUnloadNow")

since the documentation to /EXPORTS says:

Do not specify the decorated form of C identifiers that are declared __cdecl
or __stdcall.


But this results in:

dll2.obj : warning LNK4104: export of symbol 'DllCanUnloadNow' should be
PRIVATE
Creating library dll2.lib and object dll2.exp
dll2.exp : error LNK2001: unresolved external symbol DllCanUnloadNow
dll2.dll : fatal error LNK1120: 1 unresolved externals

mh?

then i tried the decorated form:

#pragma comment(linker, "/EXPORT:_DllCanUnloadNow@0")

and now i looks as it is ok.

comments?

thx a lot for your help!

mario


Ben Voigt [C++ MVP]

unread,
Mar 13, 2008, 4:31:47 PM3/13/08
to

But now the name is wrong, when COM looks for "DllCanUnloadNow" with
GetProcAddress, it won't find it.

Mario Semo

unread,
Mar 13, 2008, 4:41:14 PM3/13/08
to
Ben,

"Ben Voigt [C++ MVP]" <r...@nospam.nospam> schrieb im Newsbeitrag
news:OLt6fjUh...@TK2MSFTNGP04.phx.gbl...


>>
>> #pragma comment(linker, "/EXPORT:DllCanUnloadNow")
>>
>>

>> #pragma comment(linker, "/EXPORT:_DllCanUnloadNow@0")
>>

> But now the name is wrong, when COM looks for "DllCanUnloadNow" with

> GetProcAddress, it won't find it.
>

But
a) extern "C" __stdcall functions are always mangeled (decorated) by VC++
and the function is prototyped this way.
b) what whould be the correct way to export?
c) when i ignore the prototype in the windows header file and change it to

extern "C" __declspec(dllexport) unsigned long __stdcall DllCanUnloadNow()
/* use unsigned long instead of HRESULT so i do not need to include
windows.h */

and implement this function, then i have 2 binaries based on 2 different
sources:

=== dll1.cpp ===
#include <windows.h>
STDAPI DllCanUnloadNow()
{ return 0; }

//#pragma comment(linker, "/EXPORT:DllCanUnloadNow") // this will give a
linker error since __stdcall functions are decorated.


#pragma comment(linker, "/EXPORT:_DllCanUnloadNow@0")

=================

===== dll2.cpp =======
extern "C" __declspec(dllexport) unsigned long __stdcall DllCanUnloadNow()
/* use unsigned long instead of HRESULT so i do not need to include
windows.h */
{
return 0;
}
==================

and dumpbin /Exports dll.dll
(for both dlls)

gives exactly the same result!

1 0 00001005 _DllCanUnloadNow@0 = @ILT+0(_DllCanUnloadNow@0)

So, the question is : how to implement DllCanUnloadNow with VC++ (without
.DEF file)

thx,
mario.


Ben Voigt [C++ MVP]

unread,
Mar 13, 2008, 4:50:13 PM3/13/08
to
> and dumpbin /Exports dll.dll
> (for both dlls)
>
> gives exactly the same result!
>
> 1 0 00001005 _DllCanUnloadNow@0 =
> @ILT+0(_DllCanUnloadNow@0)
> So, the question is : how to implement DllCanUnloadNow with VC++
> (without .DEF file)

Only a DEF file lets you control the name in the exports table.

>
> thx,
> mario.


0 new messages