Community
cancel
Showing results for 
Search instead for 
Did you mean: 
anine
Beginner
88 Views

Can use reference pointer of managed code in class of TBB?

I have a problem. I want to use reference pointer(as array^) in parallel_for.

for example:

class ApplyFoo {
char *const my_a;
public:
void operator( )( const blocked_range& r ) const {
char *a = my_a;
for( size_t i=r.begin(); i!=r.end( ); ++i )
Foo(a);
}
ApplyFoo( char a[] ) :my_a(a){}
};

void ParallelApplyFoo( char a[], size_t n ) {
parallel_for(blocked_range(0,n,YouPickAGrainSize), ApplyFoo(a) );
}

I want to replace char* with array^. How should I do?

Thanks.

0 Kudos
10 Replies
Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - anine

I have a problem. I want to use reference pointer(as array^) in parallel_for.

I want to replace char* with array^. How should I do?

There are several ways.

First is to use gcroot<> wrapper which is able to hold a reference to an object in managed heap. It uses InteropServices internally to accomplish this task.

[cpp]#include 

class ApplyFoo
{
    gcroot a;
    ApplyFoo(array^ aa)
    {
        a = aa;
    }
};

[/cpp]

Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - Dmitriy V'jukov

There are several ways.

First is to use gcroot<> wrapper which is able to hold a reference to an object in managed heap. It uses InteropServices internally to accomplish this task.

[cpp]#include 

class ApplyFoo
{
gcroot a;
ApplyFoo(array^ aa)
{
a = aa;
}
};

[/cpp]

S@#$! Syntaxhighlighter eats templates!

#include

class ApplyFoo
{
gcroot^> a;
ApplyFoo(array^ aa)
{
a = aa;
}
};

Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - Dmitriy V'jukov

There are several ways.

Second is to use GCHandle class. Here you have to manualy allocate and free references to managed objects:

using namespace System;
using namespace System::Runtime::InteropServices;

class ApplyFoo
{
IntPtr a;

ApplyFoo(array^ aa)
{
a = static_cast(GCHandle::Alloc(aa));
}

~ApplyFoo()
{
static_cast(a).Free();
}

void f()
{
array^ aa = safe_cast^>(static_cast(a).Target);
// use aa
}
};

Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - Dmitriy V'jukov

There are several ways.

Third is to 'pin' managed object. When you pin the object, you are able to get native pointer to it. While there is a live pin_ptr for object, it won't move in managed heap. Native pointer is valid only while pin_ptr exists.

struct ApplyFoo
{
char* a;

ApplyFoo(char* aa)
{
a = aa;
}

void operator () (tbb::blocked_range const& r) const {}
};

void ParallelApplyFoo(array^ a, size_t n)
{
pin_ptr aa = &a[0];
tbb::parallel_for(tbb::blocked_range(0, n, 1), ApplyFoo(aa));
}

AJ13
New Contributor I
88 Views

And what about standard C++? I checked online, having never heard of these constructs... they all seem to be MS creations outside the standard.

anine
Beginner
88 Views

Your answer has a lot of favor for me. Thank you for your help very much.

Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - AJ

And what about standard C++? I checked online, having never heard of these constructs... they all seem to be MS creations outside the standard.

Yes, these are MS creations outside standard. Exactly like objects in managed CLI heap themselves.

So we are talking here about so called C++/CLI, not ISO C++. Fortunately C++/CLI is a kind of superset of ISO C++, so TBB can be compiled as C++/CLI.

RafSchietekat
Black Belt
88 Views

I almost had a heart attack myself, so I propose that this stuff be properly flagged in advance (as "C++/CLI", not "managed code").

Dmitry_Vyukov
Valued Contributor I
88 Views

Quoting - Raf Schietekat

I almost had a heart attack myself, so I propose that this stuff be properly flagged in advance (as "C++/CLI", not "managed code").

C++/CLI is exactly managed code, or ".NET" if you want.

Or more precisely, it's "ISO C++" + ".NET".

RafSchietekat
Black Belt
88 Views

Quoting - Dmitriy V'jukov

C++/CLI is exactly managed code, or ".NET" if you want.

Or more precisely, it's "ISO C++" + ".NET".

Anyone who knows that doesn't need to be warned anymore.

Reply