Returning array of strings through callback from unmanaged to mana

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have seen documentation that CF 2.0 supports arrays through interop. I
cannot find any solid examples of how to do this.

What I want to accomplish is to pass a callback function to unmanaged code.
One of the parameters in the callback function is an array of strings. The
unmanaged code will save the callback function and start a timer. When the
timer fires, I need to be able to create an array of strings and pass that
back through the callback function to the managed code.

Does anyone have a code sample for this?
 
The challenge is who's going to own the allocated memory? If it's the
method making the callback, then how does it ever get freed? If it's the
target of the callback, how does it know how much space to allocate?
Strictly speaking you could probably marshal them as an array of IntPtrs,
then do an IntPtr to String on each, but the potential for eitehr leaks or
invalid memory access is just too high. I'd consider rearchitecting.

-Chris
 
Thanks for your reply.

It is imperative that I am able to return the array of strings from the
callback function. I am dealing with a third party unmanaged C++ dll on the
Pocket PC. I need to keep the bulk of my code that uses this dll in
unmanaged code. Otherwise I will run into leaks and quirks with this third
party dll trying to access it through interop with the Compact
framework(which I do have working, but I am running into the issues with
invalid memory access).

I have control over how many strings I want the unmanaged code to return to
me. My thought process on this is to create a GCHandle for an array of a set
number of strings. This has the managed code owning the memory space and
eliminates the worries of the .NET framework if it moves the memory on me.

Now I am to point of guessing. Does each string have to be initialized with
dummy data so it occupies memory? I do not know what the rules are on this.

Next I like the idea of passing an array of IntPtrs to the unmanaged code.
I can work out the C++ code to put my string data into the pointers. I can
guess my way through alot of this, I am just hoping someone has more in depth
knowledge about this than I possess to help me accomplish this.
 
Is the array of strings a jagged array or fixed length array? How they are
allocated in native will greatly dictate how you have to handle them here.
My guess is that you'll have to create an array of IntPtrs pointing to
pinned, allocated memory for each string. But how does the native code get
access to that array? You pass it in somewhere else? Basically we're
missing the interface piece of this puzzle. If you have a requirement based
on some existing C method or methods, then post their function prototypes.

-Chris
 
I'd go in a slightly different way. Make a callback signature look like
this:
C++:
void Callback(LPTSTR* ppStringArray, int cArray)
C#:
void Callback(IntPtr ppStringArray, int cArray)

Put your strings in a construct like this.
LPTSTR MyStrings[]
Allocate your strings on the unmanaged side and fill them. Call the
callback.
On the managed side when you are invoked walk the pointer in a loop by
calling Marshal.ReadIntPtr() and for each pointer you get use
Marshal.PtrToStringUni to get the actual string (a copy of it). Now your
managed code contains a copy of this string array and you can free the
unmanaged memory if you wish
 
Thanks Alex. This was the information I was looking for. Thank you for
taking time out to answer my question.

Alex Feinman said:
I'd go in a slightly different way. Make a callback signature look like
this:
C++:
void Callback(LPTSTR* ppStringArray, int cArray)
C#:
void Callback(IntPtr ppStringArray, int cArray)

Put your strings in a construct like this.
LPTSTR MyStrings[]
Allocate your strings on the unmanaged side and fill them. Call the
callback.
On the managed side when you are invoked walk the pointer in a loop by
calling Marshal.ReadIntPtr() and for each pointer you get use
Marshal.PtrToStringUni to get the actual string (a copy of it). Now your
managed code contains a copy of this string array and you can free the
unmanaged memory if you wish

Bruce Parker said:
Thanks for your reply.

It is imperative that I am able to return the array of strings from the
callback function. I am dealing with a third party unmanaged C++ dll on
the
Pocket PC. I need to keep the bulk of my code that uses this dll in
unmanaged code. Otherwise I will run into leaks and quirks with this
third
party dll trying to access it through interop with the Compact
framework(which I do have working, but I am running into the issues with
invalid memory access).

I have control over how many strings I want the unmanaged code to return
to
me. My thought process on this is to create a GCHandle for an array of a
set
number of strings. This has the managed code owning the memory space and
eliminates the worries of the .NET framework if it moves the memory on me.

Now I am to point of guessing. Does each string have to be initialized
with
dummy data so it occupies memory? I do not know what the rules are on
this.

Next I like the idea of passing an array of IntPtrs to the unmanaged code.
I can work out the C++ code to put my string data into the pointers. I
can
guess my way through alot of this, I am just hoping someone has more in
depth
knowledge about this than I possess to help me accomplish this.
 
Back
Top