Using HECRAS Controller in csharp

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Using HECRAS Controller in csharp

iamchriskelley
Hi Everyone,

Thanks to posts on this forum I've gotten the HECRASController running in VBA, and now I'd like to get it running in C# (in the back end of a Unity3D application). I've added the reference to my C# project and the COM interop is working fine for simple things like Project_Open() and HECRASVersion().

I'm currently stuck on Compute_CurrentPlan. In VBA I can easily do this in a few lines, like:

Sub foobar()
Dim hrc As New HECRASController
Dim i As Long
Dim msgs() As String
Dim b As Boolean
hrc.Project_Open "[path]"
b = hrc.Compute_CurrentPlan(i, msgs(), True)
End Sub

C# is much pickier with types though, and Compute_CurrentPlan in C# seems to require an Array type (not a string[] array) passed by reference.

Currently I have (apologies for not yet knowing the code markups for this forum):

using RAS503;
using System;
using UnityEngine;

public class HECRAS_runner0 : MonoBehaviour {

    public HECRASController hrc;

    void Start () {
        int nmsg = 0;
        bool block = true;
        Array sa = Array.CreateInstance(typeof(string), 100);
        //sa.SetValue("", 0);
       
        hrc = new HECRASController();
        Debug.Log(hrc.HECRASVersion());
        hrc.Project_Open("[path]");
        Debug.Log(hrc.Project_Current());
        Debug.Log(hrc.CurrentProjectTitle());
        hrc.Compute_ShowComputationWindow();
        Debug.Log(hrc.CurrentGeomFile());
        Debug.Log(hrc.CurrentSteadyFile());
        Debug.Log(hrc.CurrentProjectFile());
        Debug.Log(hrc.CurrentPlanFile());

        try
            {
                hrc.Compute_CurrentPlan(ref nmsg, ref sa, ref block);
            }
        catch (Exception e)
            {
                Debug.Log(e.ToString());
            }

        hrc.Project_Save();
        hrc.Project_Close();
        hrc.QuitRas();
        Debug.Log("done.");
        hrc = null; //kills the process faster than waiting for GC
    }
}

(The capacity of sa was set to 100 to try and give enough room; setting it to 1 or 1000 doesn't seem to make a difference). This gives the following error:

System.ArgumentException: Value does not fall within the expected range.
  at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR (Int32 errorCode) [0x0000d] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs:1031
  at (wrapper cominterop) RAS503.HECRASControllerClass:Compute_CurrentPlan (int&,System.Array&,bool&)
  at (wrapper cominterop-invoke) RAS503.HECRASControllerClass:Compute_CurrentPlan (int&,System.Array&,bool&)
  at HECRAS_runner0.Start () [0x000b4] in C:\Users\Admin\Documents\HEC-RAS_demo\Assets\HECRAS_runner0.cs:32
UnityEngine.Debug:Log(Object)
HECRAS_runner0:Start() (at Assets/HECRAS_runner0.cs:36)

Has anyone had experienced using HECRASController in C# or another strongly typed language and have any insights?

Thanks!
Chris
Reply | Threaded
Open this post in threaded view
|

Re: Using HECRAS Controller in csharp

Chris G.
Administrator
Chris, you might be breaking new ground doing this in C #. Thanks for blazing the trail. I wish I had C# experience to help. Hopefully someone else can chime in. If you figure it out, please post here. Thanks-
Chris
Chris G.
@RASModel
www.therassolution.com
Reply | Threaded
Open this post in threaded view
|

Re: Using HECRAS Controller in csharp

iamchriskelley
Thanks for the reply, Chris. I'll keep plugging away. If anyone has any suggestions please let me know.
Reply | Threaded
Open this post in threaded view
|

Re: Using HECRAS Controller in csharp

iamchriskelley
Okay, got it! The following code is working in C# (with a reference to the HECRASController):

        hrc = new HECRASController();
        int nmsg = 0;
        bool block = true;
        Array sa = null;
        hrc.Project_Open("[path]");
        hrc.Compute_ShowComputationWindow();

        try
        {
            hrc.Compute_CurrentPlan(ref nmsg, ref sa, ref block);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        hrc.Project_Save();
        hrc.Project_Close();
        hrc.QuitRas();

The System.Array has to be nulled for Compute_CurrentPlan() to accept it (confirmed by Caleb Buahin who wrote the RCAFF application in C#).