Пример #1
0
 private static extern Error vbaiSetVariables(NativeSession session, VariableUpdateMode updateMode, VariableValuePriv[] variableArray, int size);
Пример #2
0
        public void SetVariables(VariableUpdateMode updateMode, VariableValue[] variableArray)
        {
            if (variableArray == null)
            {
                throw new ArgumentException("variableArray");
            }

            if (variableArray.Length == 0)
            {
                throw new ArgumentException("variableArray is empty");
            }

            VariableValuePriv[] variables        = new VariableValuePriv[variableArray.Length];
            List <IntPtr>       HandlesToDispose = new List <IntPtr>();

            for (int i = 0; i < variableArray.Length; i++)
            {
                VariableValueUnion val = new VariableValueUnion();
                variables[i].name = variableArray[i].name;
                variables[i].type = variableArray[i].type;
                switch (variableArray[i].type)
                {
                case VariableDataType.BooleanVariableType:
                    val.boolValue = variableArray[i].boolValue;
                    break;

                case VariableDataType.NumericVariableType:
                    val.numValue = variableArray[i].numValue;
                    break;

                case VariableDataType.StringVariableType:
                    val.strValue = Marshal.StringToHGlobalAnsi(variableArray[i].strValue);
                    HandlesToDispose.Add(val.strValue);
                    break;

                case VariableDataType.PointVariableType:
                    val.pointValue = variableArray[i].pointValue;
                    break;

                case VariableDataType.ImageVariableType:
                    val.imgValue = variableArray[i].imgValue._image;
                    break;

                case VariableDataType.Numeric1DVariableType:
                    val.num1DValue = Marshal.AllocHGlobal(sizeof(double) * variableArray[i].num1DValue.Length);
                    Marshal.Copy(variableArray[i].num1DValue, 0, val.num1DValue, variableArray[i].num1DValue.Length);
                    variables[i].arraySize = variableArray[i].num1DValue.Length;
                    HandlesToDispose.Add(val.num1DValue);
                    break;

                case VariableDataType.Boolean1DVariableType:
                    // Unmanaged code has 4 bytes for bool and managed code only has 1 byte.
                    // When copying 1 byte into 4 byte data space, need to make sure memory is initialized to all zeros so when we set one byte to false (0),
                    // we don't have to worry about remaining 3 bytes possibly having data that would make the False look like a True in C code.
                    int boolSizeinBytes = Marshal.SizeOf(new bool()) * variableArray[i].bool1DValue.Length;

                    IntPtr currentLocation = val.bool1DValue = Marshal.AllocHGlobal(boolSizeinBytes);
                    byte[] emptyByteArray  = new byte[boolSizeinBytes];
                    Marshal.Copy(emptyByteArray, 0, currentLocation, boolSizeinBytes);
                    for (int j = 0; j < variableArray[i].bool1DValue.Length; j++)
                    {
                        Marshal.WriteByte(currentLocation, Convert.ToByte(variableArray[i].bool1DValue[j]));
                        currentLocation = new IntPtr(currentLocation.ToInt64() + Marshal.SizeOf(new bool()));
                    }
                    variables[i].arraySize = variableArray[i].bool1DValue.Length;
                    HandlesToDispose.Add(val.bool1DValue);
                    break;

                case VariableDataType.String1DVariableType:
                    IntPtr[] stringArray = new IntPtr[variableArray[i].str1DValue.Length];
                    for (int j = 0; j < variableArray[i].str1DValue.Length; j++)
                    {
                        stringArray[j] = Marshal.StringToHGlobalAnsi(variableArray[i].str1DValue[j]);
                        HandlesToDispose.Add(stringArray[j]);
                    }
                    val.str1DValue = Marshal.AllocHGlobal(Marshal.SizeOf(new IntPtr()) * stringArray.Length);
                    Marshal.Copy(stringArray, 0, val.str1DValue, variableArray[i].str1DValue.Length);

                    HandlesToDispose.Add(val.str1DValue);

                    variables[i].arraySize = variableArray[i].str1DValue.Length;
                    break;

                default:
                    break;
                }
                variables[i].value = val;
            }
            Error err = vbaiSetVariables(_session.nativeSession, updateMode, variables, variables.Length);

            if (err != Error.Success)
            {
                ExceptionBuilder.CheckErrorAndThrow(err);
            }

            // Free allocated data
            for (int i = 0; i < HandlesToDispose.Count; i++)
            {
                Marshal.FreeHGlobal(HandlesToDispose[i]);
            }
            HandlesToDispose.Clear();
        }