Calling Methods that have ByRef or Out Parameters

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:

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

The proxy generator creates a FoxPro method like this:

************************************************************************
*  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:

*** 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