tags:

views:

202

answers:

4

I'm building a .NET client and I referenced a RCW supplied by OPC Foundation.

One of the functions has this parameter:

[IN] IntPtr pPercentDeadBand

The documentation mention that I should pass a pointer to a float value.

This is where I struggle. I found Marshall..WriteByte, .WriteInt16 and .Writeint32.

But nothing to write a float value from managed memory to unmanaged memory.

A: 

If it's the OPC Foundation, it appears as though they have a managed code API. UA SDK 1.00 includes support for .NET development environments, according to opcconnect.com.

TrueWill
A: 

Yes they do but you need to be a member (1000$ to 1500$). I'm trying the free way by doing interop.

thanks

kevin marchand
A: 

You can use Marshal.Copy instead and pass in a float[] with a single element.

Or you could stuff the bits from a float into an int and use Marshal.WriteInt32. This union-like struct can be used to convert between the two

[StructLayout(LayoutKind.Explicit)]
struct SingleInt32Union
{
    [FieldOffset(0)]
    float s;
    [FieldOffset(0)]
    int i;
}
Mattias S
+1  A: 

I would do it in one of these ways, ordered from best to worst solution:

  1. Change the Interop assembly definition of this method. If it is a pointer to a float it should be declared as follows.

    ref float pPercentDeadBand
    

    not

    [In] IntPtr pPercentDeadBand
    
  2. Use unsafe code to pass a pointer to a float:

    unsafe
    {
        float theValueToPass = 345.26f;
        IntPtr thePointer = new IntPtr(&theValueToPass);
        //pass thePointer to the method;
    }
    
  3. Allocate 4 bytes of memory using Marshal.AllocHGlobal, copy the float value from a single element float array using Marshal.Copy, call the method using the pointer received from Marshal.AllocHGlobal and then free the memory with Marshal.FreeHGlobal.

Stephen Martin