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

exporting friend functions

1,682 views
Skip to first unread message

Larry

unread,
Mar 26, 1998, 3:00:00 AM3/26/98
to

I am an admitted Visual C++ newbie.

Can anyone tell me how to export a friend function
of an exported class within a DLL ?

Although friend functions are declared within a class,
they are not class member functions, hence specifying
__declspec( dllexport ) before the class name, such as:

class __declspec( dllexport ) MyInt
{
friend ostream& operator<<( ostream& os, MyInt& s );

public:
MyInt( int iP ) : i( iP ) {}

private:
int i;
};

does not export the friend function. This was evident to me
in the following linker error I got trying to link my DLL.

main.obj : error LNK2001: unresolved external symbol "class ostream &
__cdecl operator<<(class ostream &,class MyInt &)"
(??6@YAAAVostream@@AAV0@AAVMyInt@@@Z)
Debug/DLL_exe.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

DLL_exe.exe - 2 error(s), 1 warning(s)

Les Matheson

unread,
Mar 26, 1998, 3:00:00 AM3/26/98
to

Just make sure you declare the friend function itself with
__declspec(dllexport):

// myfile.h
class __declspec(dllexport) MyClass
{
friend void __declspec(dllexport) myFriend();
public:

};

// myfile.cpp
void __declspec(dllexport) myFriend()
{
}

Les
*** Reply email address: nospam-l...@mindspring.com


Larry wrote in message <351B1A...@erols.com>...

Larry

unread,
Mar 28, 1998, 3:00:00 AM3/28/98
to

Les,

Thanks for your reply.

I had already tried many combinations including the one you
suggested. I noticed when I run DUMPBIN /EXPORTS on the dll
file, it does not show the friend function. I will include
my library code and the executable code that links that library;
I would be very greatful if you could take more time to help me.

-------------------------------------------------------------------
My Library header (lib.h):

#define DllImport __declspec( dllimport )
#define DllExport __declspec( dllexport )

#ifdef _EXPORTING
#define DllImpExp __declspec( dllexport )
#else
#define DllImpExp __declspec( dllimport )
#endif

void DllImpExp func( int i );

class DllImpExp MyInt
{
friend ostream& DllImpExp operator<<( ostream& os, MyInt& s );

public:
MyInt( int iP ) : i( iP ) {}

private:
int i;
};

-------------------------------------------------------------------
My library implementation file (lib.cpp):

#include <iostream.h>

#define _EXPORTING

#include "lib.h"

void DllExport func( int i )
{
cout << "func: i = " << i << endl;
};

ostream& DllExport operator<<( ostream& os, MyInt& s )
{
os << s << endl;

return os;
}

-------------------------------------------------------------------
My exe implementation file (main.cpp):

#include <iostream.h>
#include "lib.h"

main()
{
MyInt m( 3 );

cout << m;

func( 5 );

return 0;
}

-------------------------------------------------------------------
DUMPBIN of lib.dll:

E:\C++ Projects\_lib>dumpbin /exports DLL_lib.dll
Microsoft (R) COFF Binary File Dumper Version 5.00.7022
Copyright (C) Microsoft Corp 1992-1997. All rights reserved.


Dump of file lib.dll

File Type: DLL

Section contains the following Exports for lib.dll

0 characteristics
351C9948 time date stamp Sat Mar 28 01:31:36 1998
0.00 version
1 ordinal base
3 number of functions
3 number of names

ordinal hint name

1 0 ??0MyInt@@QAE@H@Z (00001014)
2 1 ??4MyInt@@QAEAAV0@ABV0@@Z (00001019)
3 2 ?func@@YAXH@Z (00001023)

Summary

7000 .data
1000 .idata
3000 .rdata
2000 .reloc
1D000 .text

-------------------------------------------------------------------
End of long message (sorry)...

Les Matheson

unread,
Mar 28, 1998, 3:00:00 AM3/28/98
to

. I noticed when I run DUMPBIN /EXPORTS on the dll
>file, it does not show the friend function. I will include
>my library code and the executable code that links that library;
>I would be very greatful if you could take more time to help me.
>
>

>class DllImpExp MyInt
>{
> friend ostream& DllImpExp operator<<( ostream& os, MyInt& s );
>

-- Sorry, my mistake: it should say:

friend DllImpExp ostream & operator <<(ostream&....

*NOT*
friend ostream & DllImpExp operator << (ostream&...

IMHO, the compiler should have complained about the former, since
__declspec()
is part of the decl-specifier in the C++ grammar, not part of the
declarator, and thus should
always come before the return type.

-- By the way, the following construct, while it works fine if your DLL's
don't ever reference
each other, will become a problem when they do. If DLL_1 references
functions defined
by DLL_2, and both use the macro _EXPORTING, the linker will expect both
DLL's to
define the functions exported by DLL_1.

>#ifdef _EXPORTING
>#define DllImpExp __declspec( dllexport )
>#else
>#define DllImpExp __declspec( dllimport )
>#endif


The best solution I know of for this is to define a custom macro for each
DLL like this:

#if (PROJECTNAME="DLL_1")
#define IMPEXP_DLL1 __declspec(dllexport)
#else
#define IMPEXP_DLL1 __declspec(dllimport)
#endif

Then, in the DLL_1 project build settings, under the C++ / Preprocessor
category, add a definition
for PROJECTNAME="DLL_1". Thus any other DLL's which import DLL_1 won't get
confused.
This method has another beneficial side-effect: since each macro contains
the name of the DLL
which exports the symbol, it is much easier when sifting through a lot of
header files to remember
which DLL contains the implementation for any name.

Good luck,
Les


0 new messages