PInvoke - Pinning byte arrays

I

_iycrd

After numerous problems, I'm having second thoughts about using
C++/CLI to wrap a native DLL. On the other hand, PInvoke seems like
it will take a huge amount of work, if it will work at all.

The native DLL uses raw data buffers that are normally handed to it
(via pointer) from another native function. If I'm piloting this with
C#/PInvoke, how could those raw data buffers be created and
immobilized? In C++/CLI, there is pin_ptr to keep the CLR's memory
manager from moving things, but I don't see how this can be done in
C#/PInvoke. Can it?
 
W

Willy Denoyette [MVP]

Native memory buffers don't need to be pinned, they are not a subject of the
GC.

Willy.

| After numerous problems, I'm having second thoughts about using
| C++/CLI to wrap a native DLL. On the other hand, PInvoke seems like
| it will take a huge amount of work, if it will work at all.
|
| The native DLL uses raw data buffers that are normally handed to it
| (via pointer) from another native function. If I'm piloting this with
| C#/PInvoke, how could those raw data buffers be created and
| immobilized? In C++/CLI, there is pin_ptr to keep the CLR's memory
| manager from moving things, but I don't see how this can be done in
| C#/PInvoke. Can it?
|
 
S

Stoitcho Goutsev \(100\)

Hi,

I'm not exactlu sure I understand your question correctly. Maybe Willy
already answered your question, but just in case if you want to pin a object
in the managed heap so the GC won't move it arround you need to create a
GCHandle to it of type Pinned such as

GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);

To unpin the object use GCHandle.Free method.

GCHandles can be converted to and from IntPtr for using with PInvoke.

Keep in mind that pinning objects in managed heap can undermine GC
efficiency.
 
B

Brian Gideon

If you declare the API correctly the framework will marshal data types
for you and ensure that they are either copied or pinned. In the case
of blittable types (a byte array is blittable) they are pinned during
marshaling.

Consider the following DllImport declarations.

[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr dst, IntPtr src, long
length);

or

[DllImport("kernel32.dll")]
public static extern void CopyMemory(byte[] dst, byte[] src, long
length);

You can make both declarations work, but in the first example you would
have to obtain a pointer to your buffer and the pin/unpin it manually.
If you declare the API similar to the second example then the marshaler
will do all of this for you.

Brian
 
W

Willy Denoyette [MVP]

| On Thu, 9 Mar 2006 14:13:22 +0100, "Willy Denoyette [MVP]"
|
| >Native memory buffers don't need to be pinned, they are not a subject of
the
| >GC.
| >
| >Willy.
|
| Hi Willy,
|
| Does C# have provision for creating native buffers?
|

If you mean buffers in the process heap instead of the GC heap, look at the
Marshal class, there are a number of methods (AllocHGloba, AllocCoTaskMem)
that do just that.

Willy.
 

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