How to dllimport a dllexported class

  • Thread starter vivekanandaprasanth
  • Start date
V

vivekanandaprasanth

hi,

I have exported a class which i have written in win32 static lib app.
Now i have written a wrapper class for the same. But when i am trying
to compile it is giving me some linker errors. Here is the class
information

//This is MyClass.h file

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

class DllExport CMyClass
{
public:
CMyClass();
int GetSum(int a, int b);
};

//This is MyClass.cpp file

#include "MyClass.h"

CMyClass::CMyClass()
{
}
int CMyClass::GetSum(int a, int b)
{
return a+b;
}

After this i have created a .net class library in which i want to use
this class

// WrapperClasseApp.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
#include "D:\New Projects\MyStaticLib\MyClass.h"

namespace WrapperClasseApp
{
public __gc class Class1
{
// TODO: Add your methods for this class here.
private:
CMyClass *m_pClass;

public:
Class1::Class1(void)
{
m_pClass = new CMyClass();
}
Class1::~Class1(void)
{
delete m_pClass;
}

int WrapperForGetSum(System::Int32 a, System::Int32 b)
{
int iResult = m_pClass->GetSum(a,b);
return iResult ;
}
};
}

When i am trying to complie the above app, there are two linker errors

WrapperClasseApp.obj : error LNK2001: unresolved external symbol "void
* __cdecl operator new(unsigned int)" (??2@$$FYAPAXI@Z)
WrapperClasseApp.obj : error LNK2001: unresolved external symbol "void
__cdecl operator delete(void *)" (??3@$$FYAXPAX@Z)

can any one please help me how i can use the exported class and its
members
 
D

Doug Harrison [MVP]

hi,

I have exported a class which i have written in win32 static lib app.

There's no concept of exporting a class from a static library. Also,
"static lib app" is sort of a contradiction; it's either a library or
application, not both.
Now i have written a wrapper class for the same. But when i am trying
to compile it is giving me some linker errors. Here is the class
information

//This is MyClass.h file

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

This won't work. You need to do something like the following, replacing X
with a suitably unique identifier, which can often just be the name of your
DLL:

#ifdef COMPILING_X_DLL
#define X_EXPORT __declspec(dllexport)
#else
#define X_EXPORT __declspec(dllimport)
#endif

Then you /D COMPILING_X_DLL in the DLL's project, and only there. You would
then write:

class X_EXPORT MyClass...

That said, it doesn't make any sense to do any of this in a static library.
You need to eliminate your existing DllExport/DllImport usage.
{
public:
CMyClass();
int GetSum(int a, int b);
};

//This is MyClass.cpp file

#include "MyClass.h"

CMyClass::CMyClass()
{
}
int CMyClass::GetSum(int a, int b)
{
return a+b;
}

After this i have created a .net class library in which i want to use
this class

// WrapperClasseApp.h
#pragma once
using namespace System;
using namespace System::Runtime::InteropServices;
#include "D:\New Projects\MyStaticLib\MyClass.h"

namespace WrapperClasseApp
{
public __gc class Class1
{
// TODO: Add your methods for this class here.
private:
CMyClass *m_pClass;

public:
Class1::Class1(void)
{
m_pClass = new CMyClass();
}
Class1::~Class1(void)
{
delete m_pClass;
}

The "Class1::" bit isn't needed.
int WrapperForGetSum(System::Int32 a, System::Int32 b)
{
int iResult = m_pClass->GetSum(a,b);
return iResult ;
}
};
}

When i am trying to complie the above app, there are two linker errors

I thought it was a library. :)
WrapperClasseApp.obj : error LNK2001: unresolved external symbol "void
* __cdecl operator new(unsigned int)" (??2@$$FYAPAXI@Z)
WrapperClasseApp.obj : error LNK2001: unresolved external symbol "void
__cdecl operator delete(void *)" (??3@$$FYAXPAX@Z)

can any one please help me how i can use the exported class and its
members

You do need to link to the CRT, and all files in this library should have
the same CRT setting, e.g. /MD.
 
B

Ben Voigt [C++ MVP]

can any one please help me how i can use the exported class and its
You do need to link to the CRT, and all files in this library should
have the same CRT setting, e.g. /MD.

And many other compiler and runtime library options need to match, including
packing, alignment, use of checked iterators, the list goes on and on.

Please don't use dllexport on classes. Expose functions which take the
instance as a argument, like the Win32 API does, or use a factory function
to return a pointer to a pure interface class, like COM. These solutions
are well-known, tested, portable, and resilient to changes.
 
D

Doug Harrison [MVP]

And many other compiler and runtime library options need to match, including
packing, alignment, use of checked iterators, the list goes on and on.

Right. Using DLLs is no different that using static libraries in that
respect.
Please don't use dllexport on classes. Expose functions which take the
instance as a argument, like the Win32 API does, or use a factory function
to return a pointer to a pure interface class, like COM. These solutions
are well-known, tested, portable, and resilient to changes.

Alternatively, understand that when you share C++ classes across module
boundaries, you need to treat it like static linking WRT having identical
project settings for the things you mentioned. Given the goal of sharing
C++ objects across module boundaries, how could it be any different?

Anyone interested in a discussion of these points of view should refer to
these threads, as I'm not going to rehash it any further here:

http://groups.google.com/group/micr...e1db774fd/3036d22e7c902105?hl=en?d22e7c902105
http://groups.google.com/group/micr...855c/e918f517c973340f?hl=en&#e918f517c973340f

P.S. Anyone who changes the default packing really is asking for trouble.
It's very unlikely to work with third party code, as few are as diligent as
MS at setting and restoring the packing. And MS gets (or use to get) it
wrong sometimes, as was the case in <winsock2.h>, TEXTMETRICW, and at least
one other I've forgotten. In contrast, exporting whole classes works
flawlessly for probably thousands of programs that use the CRT DLLs, MFC
extension DLLs, etc etc etc, and observe the similarity to static linking
and take care with template static data.
 
V

vivekanandaprasanth

hi Ben,

" Expose functions which take the
instance as a argument, like the Win32 API does, or use a factory
function
to return a pointer to a pure interface class, like COM. "

Can you just expand the above......I couldnt understand what your
intention was. How can I return a pointer to a interface?
If you don't mind can you please take out an example and let me know
how to achieve that. The reply what I got was very helpful to me since
I am entirely new to this.

very very very thanks in advance
 
D

David Wilkinson

hi Ben,

" Expose functions which take the
instance as a argument, like the Win32 API does, or use a factory
function
to return a pointer to a pure interface class, like COM. "

Can you just expand the above......I couldnt understand what your
intention was. How can I return a pointer to a interface?
If you don't mind can you please take out an example and let me know
how to achieve that. The reply what I got was very helpful to me since
I am entirely new to this.

vivekanandaprasanth:

The DLL has a concrete class that derives from a pure interface. The exported
factory function returns a pointer to an instance of the concrete class, which
is also a valid pointer to the interface. The client application only knows
about the interface.

It is also a good idea to export a function (anti-factory) that destroys the
instance; this avoids problems with different heaps in the two modules.

This pattern allows mixed compiler version in the DLL and client, because all
compiler versions agree on the layout of a pure interface class.
 
B

Ben Voigt [C++ MVP]

hi Ben,

" Expose functions which take the
instance as a argument, like the Win32 API does, or use a factory
function
to return a pointer to a pure interface class, like COM. "

Can you just expand the above......I couldnt understand what your
intention was. How can I return a pointer to a interface?
If you don't mind can you please take out an example and let me know
how to achieve that. The reply what I got was very helpful to me since
I am entirely new to this.

If you search the msdn site for COM factory example, you might come up with
something like this:
http://blogs.msdn.com/ericlippert/archive/tags/SimpleScript/default.aspx?p=2
http://blogs.msdn.com/ericlippert/pages/108025.aspx

Expecially look at the Create, AddRef, and Release functions, along with the
constructor and destructor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top