Exposing template instances from managed c++ dll

C

cortfr

If I compile the following code in my managed c++ dll...

public ref class foo
{
public:
void doSomething() { }
};
public ref class bar { };

and then inspect the resulting dll using ildasm... I can see that foo
and bar both have a function called doSomething.

However, if foo is a template and bar inherits from it, e.g.

template <typename t>
public ref class foo
{
public:
void doSomething() { }
};
public ref class bar : public foo<System::String> { };

Then both bar and the foo template instance do not have the doSomething
function according to ildasm (and my client assemblies).

What am I doing wrong? thanks.
 
S

SvenC

Hi,

cortfr said:
If I compile the following code in my managed c++ dll...

public ref class foo
{
public:
void doSomething() { }
};
public ref class bar { };

and then inspect the resulting dll using ildasm... I can see that foo
and bar both have a function called doSomething.

However, if foo is a template and bar inherits from it, e.g.

template <typename t>
public ref class foo
{
public:
void doSomething() { }
};
public ref class bar : public foo<System::String> { };

Then both bar and the foo template instance do not have the doSomething
function according to ildasm (and my client assemblies).

What am I doing wrong? thanks.

Templates are a C++ only feature so you AFAIK you cannot expose template
classes to other .Net languages.
Use generic instead which gives you some of the functionality you have with
template:

generic<typename T>
public ref class foo...
 
C

cortfr

Hi Sven,
Thanks for the reply. Generics won't work for what I'm trying to do,
mainly because the template parameter I want to use is not a managed
class. I used a managed class (System::String) in the example above
just to simplify the question.

Anyways, I can understand why the template foo isn't exposed and usable
from other .NET languages... but I still don't understand why the
template instance (i.e. foo<System::String>) is not exposed. The
template instance should just be as if I created another class myself
by copying foo and replacing all instances of T with System::String,
right?
 
C

Carl Daniel [VC++ MVP]

cortfr said:
If I compile the following code in my managed c++ dll...

public ref class foo
{
public:
void doSomething() { }
};
public ref class bar { };

and then inspect the resulting dll using ildasm... I can see that foo
and bar both have a function called doSomething.

However, if foo is a template and bar inherits from it, e.g.

template <typename t>
public ref class foo
{
public:
void doSomething() { }
};
public ref class bar : public foo<System::String> { };

Then both bar and the foo template instance do not have the
doSomething function according to ildasm (and my client assemblies).

What am I doing wrong? thanks.

Try this:

template <typename t>
public ref class foo
{
public:
virtual void doSomething() { }
};
public ref class bar : public foo<System::String> {
public:
virtual void doSomething() override { }
};

-cd
 
C

cortfr

Ah right... thanks Carl... just setting foo's doSomething to be virtual
allows doSomething to be exposed. So that solves my problem. But it
still seems odd that you'd have to do that.
 
B

Ben Voigt

cortfr said:
Ah right... thanks Carl... just setting foo's doSomething to be virtual
allows doSomething to be exposed. So that solves my problem. But it
still seems odd that you'd have to do that.

Virtual functions have to have their address taken and placed in the
v-table. So that creates a reference to the function, and it can't be
optimized out.
 
C

cortfr

Ben, See my first post for context. Note that doSomething in foo does
NOT have to be virtual in order for bar to expose that function. But
if foo is a template, then it does have to be virtual.
thanks.
 
B

Ben Voigt

cortfr said:
Ben, See my first post for context. Note that doSomething in foo does
NOT have to be virtual in order for bar to expose that function. But
if foo is a template, then it does have to be virtual.
thanks.

Ok, good point. Still, template instantiation is driven by use, so the
v-table is considered a reference to the function and the compiler has to
generate it.

Non-template functions would normally be removed by the optimizer (in the
link stage), however exported functions are "used" by the export table
(native) or metadata (managed) and can't be removed. However templates
can't be exported...
 

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