|Do you have access to the ActiveX source code? Or is it publicly available? If you have access, could you post examples of PutData and GetData. If it's publicly available, could you please provide a link.
If GetData is updating bptr2 so that it has the same value as bptr, then I would assume that PutData simply stored the long* that was passed in (instead of copying it). Then GetData is simply passing out the same long*. If this is the case then you do not need to allocate ptr2, because GetData does not required you to pass in a pre-allocated buffer.
This really depends on how the OCX methods are written and you would need a full understanding of how they work to properly use them. For example, if the PutData does in fact save the long* that was passed in, then the code below would cause access violations:
Int32 buffer = new Int32;
buffer = 1;
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)) * 10);
Marshal.Copy(buffer, 0, ptr, 10);
int bptr = (int)ptr;
ocx.PutData(ref bptr, Marshal.SizeOf(typeof(Int32)) * 10);
buffer = 2;
IntPtr ptr2 = IntPtr.Zero;
int bptr2 = (int)ptr2;
Marshal.Copy(ptr2, buffer, 0, 10);
In the code above, the long* that was cached is freed and then is accessed later. If you are only using the OCX in a serial fashion like your example, then it would be fine.
Let me know if this makes sense.
Check out my blog at http://tjoe.wordpress.com