Calling Methods that have ByRef or Out Parameters

about 2 minutes to read

Parameters passed by reference are a bit complicated with .NET Interop. There are two ways this can be done and you can look at both approaches in the base wwDotnetBridge Documentation.

Using ComValue Structure for Ref and Out Parameters

Because the Proxy Generator generates code generically, the generator takes the ComValue approach which can be used more reliably for simple values, object and arrays, using InvokeMethod() inside of the proxy method. This provides a single mechanism for passing Ref parameters.

When the Proxy Generator creates methods with Out or Ref parameters these parameters are marked with a ref_ prefix.

Imaging you have this .NET method that has two OUT parameters:

csharp
public string UpdateVitals(string PatientId, Vitals[] PatientVitals, out Status StatusFlag, out string StatusMsg)

The proxy generator creates a FoxPro method like this:

foxpro
************************************************************************ * UpdateDataPatientVitals **************************************** FUNCTION UpdateDataPatientVitals(PatientId as String,Vitals as VitalsArray,; ref_StatusFlag as Status,ref_StatusMsg as String) ; as String LOCAL loException as Exception, lvResult as String THIS.lError = .F. this.cErrorMsg = "" lvResult = .F. TRY lvResult = this.oBridge.InvokeMethod(this.oService, "UpdateDataPatientVitals", PatientId, PatientVitals,AccountObj,; ref_StatusFlag, ref_StatusMsg) CATCH to loException THIS.GetErrorDetail(loException) ENDTRY RETURN lvResult

Notice the two ref_ parameters that are passed as regular parameters, but are marked with the prefix. These two values should be passed as ComValue objects that can marshal the parameter to .NET, and the out value back to your application.

To call this the out parameters are set up as ComValue objects:

foxpro
*** Normal array (unrelated to ref/out) loVitals = loBridge.CreateComArray("rx.Vitals") loVital = loVital.CreateItem() loVital.Status = "Ok" loVitals.AddItem(loVital) *** Create a simple type ComValue object - pass value as input loStatusString = loBridge.CreateComValue(SPACE(255)) *** More complex types have SetXXXX() methods - here an Enum is set local loStatus as rx.Status loStatus = loBrIDGE.CreateComValue() loStatus.SetEnum("rx.Status.Success") *** Call the method and return a method result loResult = loService.UpdateVitals('200089',loVitalRecords,loAccount,loStatus,loStatusString) *** Access the updated OUT parameters ? loStatus.Value && updated value ? loStatusString.Value && updated value

Note that the out result is captured by the ComValue and its Value property which should hold the updated value. wwDotnetBridge holds the value and passes it as an OUT or REF parameter to the method, the Value is updated and so your code receives the value to use.

This is not pretty, but it works and it works consistently regardless of what type of data you're passing around.


© West Wind Technologies, 2004-2020 • Updated: 02/09/18
Comment or report problem with topic