Using managed wrappers class library

M

mirek

Hi,
I've got problem building managed class library to wrap unmanaged code.

I created managed class library using standard patten:

#include "../Unmanaged/Class1.h" //Class1 unmanaged

namespace ManagedWrappers
{
public __gc MClass1
{
public:
MClass1() { m_pClass1 = new Class1(); };
~MClass1() { delete m_pClass1; };
private:
Class1* m_pClass1;
}
}

the result is ManagedWrappers.dll assembly.

Now I want to use ManagedWrappers in another project (also managed
library, let's say FooBar.dll) so I add reference to it in VS and start
using it only by managed wrappers.
But compiling this project fails:
error C3635: '::Class1': undefined native type used in
'ManagedWrappers::MClass1'; imported native types must be defined in the
importing source code did you forget to include a header file?

So do I have to include "../Unmanaged/Class1.h" in the FooBar classes?

What should I do to have ManagedWrappers assembly that will contain all
the wrapped classes and nothing will be required (besides reference) to
use it freely?

Any suggestions would be greatfully appreciated.

BTW I'd also like to know what does it do if in managed class library I
add reference to unmanaged library? Does it differ from specyfying this
library in "Additional dependency"?

Regards,
Mirek
 
J

Jochen Kalmbach

mirek said:
I've got problem building managed class library to wrap unmanaged code.

I created managed class library using standard patten:

#include "../Unmanaged/Class1.h" //Class1 unmanaged

namespace ManagedWrappers
{
public __gc MClass1
{
public:
MClass1() { m_pClass1 = new Class1(); };
~MClass1() { delete m_pClass1; };
private:
Class1* m_pClass1;
}
}

the result is ManagedWrappers.dll assembly.

Now I want to use ManagedWrappers in another project (also managed
library, let's say FooBar.dll) so I add reference to it in VS and start
using it only by managed wrappers.
But compiling this project fails:
error C3635: '::Class1': undefined native type used in
'ManagedWrappers::MClass1'; imported native types must be defined in the
importing source code did you forget to include a header file?

The problem is the namespace!

You can either define an separate namespace for the unmanaged clases or put
the unmanaged class into your managed namespace.

namespace ManagedWrappers
{
#include "../Unmanaged/Class1.h" //Class1 unmanaged

public __gc MClass1
{
public:
MClass1() { m_pClass1 = new Class1(); };
~MClass1() { delete m_pClass1; };
private:
Class1* m_pClass1;
}
}

By the way: You should avoid destructor (or better: finalizers)!!!

Better implement the IDisposable-Interface! But then the user MUST (or
should) call the Dispose-Method!

public __gc MClass1 : IDisposable
{
public:
MClass1() { m_pClass1 = new Class1(); };
void Dispose() { if (m_pClass1 == NULL) delete m_pClass1; };
private:
Class1* m_pClass1;
}


This is also usefull if the user will use your object like:

using(MClass1 m = new MClass1())
{
// do something with your class
}

The C#-using statement automatically calls "Dispose", so the user does not
need to explicitly call Dispose.



You can also implement both: Finializer and IDisposable
But finilizers should be private, because users (or programmers) should not
be able to call these; only the GC will call finilizers!)


public __gc MClass1 : IDisposable
{
public:
MClass1() { m_pClass1 = new Class1(); };
void Dispose() {
if (m_pClass1 == NULL) delete m_pClass1;
System::GC::SupressFinilizer(this);
};
private:
~MClass1() { Dispose(); }
private:
Class1* m_pClass1;
}


If the user calls Dispose, then the finilizer will not called in the GC-
destructiorn, because SupressFinilizer is called from Dispose.

If the user forgets to call Dispose, then the finilizer will call it (but
remember, that the GC will call the desructor from an DIFFERENT thread than
the object was created or used!)


So do I have to include "../Unmanaged/Class1.h" in the FooBar classes?
No.

--
Greetings
Jochen

Do you need a memory-leak finder ?
http://www.codeproject.com/tools/leakfinder.asp
 
M

mirek

Jochen said:
The problem is the namespace!

You can either define an separate namespace for the unmanaged clases or put
the unmanaged class into your managed namespace.

Thanks!! But unfortunately by unmanaged classes are not defined in
specific namespaces and I can't modify these classes. So I tried
including (inject) them to my new namespace like this:

namespace Unmanaged
{
#include "../Unmanaged/Class1.h" //Class1 unmanaged
}

namespace ManagedWrappers
{
public __gc MClass1
{
public:
MClass1() { m_pClass1 = new Unmanaged::Class1(); };
~MClass1() { delete m_pClass1; };
private:
Unmanaged::Class1* m_pClass1;
}
}

but this time this doesn't link, I get following messages on every
unmanaged classes:
LINK : error LNK2020: unresolved token (0A0001E2) Unmanaged.Class1.__dtor

It seems that I can't do this this way because the unmanagd class .obj
doesn't know abot Unmanaged namespace.
By the way: You should avoid destructor (or better: finalizers)!!!

OK, I'll try do change it. My wrappers will be also used on ASP.NET
pages and I don't know if there will be place to call Dispose() (but
then Finalizer can go.). I'll look on this.

Thanks again for your advices.

Regrads,
Mirek
 
M

mirek

It seem that if I include this as you suggested:

namespace ManagedWrappers
{
#include "../Unmanaged/Class1.h" //Class1 unmanaged

public __gc MClass1
{
public:
MClass1() { m_pClass1 = new Unmanaged::Class1(); };
~MClass1() { delete m_pClass1; };
private:
Unmanaged::Class1* m_pClass1;
}
}

I'll get the same link errors. I'm wondering if it could be done without
modyfying unmanaged class files.

Regards,
Mirek
 

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