Expose C++ array through managed wrapper class.

J

joshuapking

I'm having a very difficult time coming across an appropriate solution
for this seemingly simple problem. I've written a managed wrapper
class for some legacy C++ routines. One routine generates an array of
ints, which I wish to expose through the managed wrapper. The managed
C++ wrapper is being used as an intermediary to allow VB.NET to access
the legacy C routines (and the return array, in particular).

Given these constraints, can someone please instruct the best course of
action? I can't figure out how to define/update the C array to be .NET
compatible. Do I need to use the Marshal class? Do I need to declare
an "array<int, 1>" and use a handle (^). Any help, particularly
specific syntax examples, would be tremendous.

void returnArray(int* pArray, int& pSize); //Legacy C function

Thanks, Josh
 
K

Kurt

Without doing any research I would think you have to use a SAFEARRAY in your
managed wrapper.
 
J

joshuapking

Kurt thank you for responding. Unfortunately even if a SAFEARRAY is
the answer, I am uncertain how to properly implement it. If anyone
else has suggestions and specific examples I'd be grateful.

-Josh
 
C

Carl Daniel [VC++ MVP]

I'm having a very difficult time coming across an appropriate solution
for this seemingly simple problem. I've written a managed wrapper
class for some legacy C++ routines. One routine generates an array of
ints, which I wish to expose through the managed wrapper. The managed
C++ wrapper is being used as an intermediary to allow VB.NET to access
the legacy C routines (and the return array, in particular).

Given these constraints, can someone please instruct the best course
of action? I can't figure out how to define/update the C array to be
.NET compatible. Do I need to use the Marshal class? Do I need to
declare an "array<int, 1>" and use a handle (^). Any help,
particularly specific syntax examples, would be tremendous.

void returnArray(int* pArray, int& pSize); //Legacy C function

Based on that declaration, it looks like the caller is allocating memory
that this function will fill. If that's indeed the case, you can create a
managed array and pass a pinned pointer to the first element of that array
to your legacy function. The fact that pSize is being passed by reference
leads me to suspect that it's set to the size of the memory allocation on
input to the function, and set to the size of the actual data on return from
the function.


#pragma unmanaged
extern void r(int* p, int& s);
#pragma managed


public ref class X
{
static array<int>^ f(int s)
{
array<int>^ a = gcnew array<int>(s);
pin_ptr<int> p = &a[0];
r(p,s);
return a;
}
};

-cd
 
C

Carl Daniel [VC++ MVP]

Kurt said:
Without doing any research I would think you have to use a SAFEARRAY
in your managed wrapper.

SAFEARRAY is needed only for returning an array to VB6 or any other OLE
automation client. VB.NET can handle an array<int>^ since that's just an
ordinary CLR array.'

-cd
 
J

joshuapking

Kurt, thanks again. Carl, your example seems to be the direction I
need to head. Thank you for getting me pointed there. I will take
examine how this C++.NET class looks when viewed from VB.NET.

Can you tell me how the .NET code will differ when the C routine does
the memory allocation AND the array filling (returning an array
pointer)?

Thank you.
-Josh
 
J

joshuapking

Kurt, thanks again. Carl, your example seems to be the direction I
need to head. Thank you for getting me pointed there. I will take
examine how this C++.NET class looks when viewed from VB.NET.

Can you tell me how the .NET code will differ when the C routine does
the memory allocation AND the array filling (returning an array
pointer)?

Thank you.
-Josh
 
J

joshuapking

Kurt, thanks again. Carl, your example seems to be the direction I
need to head. Thank you for getting me pointed there. I will take
examine how this C++.NET class looks when viewed from VB.NET.

Can you tell me how the .NET code will differ when the C routine does
the memory allocation AND the array filling (returning an array
pointer)?

Thank you.
-Josh
 
J

joshuapking

Kurt, thanks again. Carl, your example seems to be the direction I
need to head. Thank you for getting me pointed there. I will take
examine how this C++.NET class looks when viewed from VB.NET.

Can you tell me how the .NET code will differ when the C routine does
the memory allocation AND the array filling (returning an array
pointer)?

Thank you.
-Josh
 
B

Ben Voigt

Kurt said:
Without doing any research I would think you have to use a SAFEARRAY in
your managed wrapper.

SAFEARRAY is for COM objects, like VB6. .NET does things differently.
 
B

Ben Voigt

Kurt, thanks again. Carl, your example seems to be the direction I
need to head. Thank you for getting me pointed there. I will take
examine how this C++.NET class looks when viewed from VB.NET.

Can you tell me how the .NET code will differ when the C routine does
the memory allocation AND the array filling (returning an array
pointer)?

Then you should allocate a managed array, memcpy the data, and free the
memory returned by the C routine in the way described in its documentation.
 

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