If this variable is not created, it leads to a crash.
I agree.
A function can also be called as a sub. The return value is then ignored by the DLL.
Agreed too (although it's VB/A ignoring the return code).
The cleaning up of the variable 'text' is done automatically by VB.
That is what I was looking for to know.
I am already very familiar with the variable type variant.
I don't doubt that for a second
I've tested both forms of declaration for the parameter (Byref Variant and Byval LongPtr).
I modified the DLL to show the passed pointer value.
So, both declaration will point to the same memory address, then there's no need to have an extra LongPtr (pVariant in your sample) that carries the VarPtr() for us.
You've got no temporary problem with your extra parenthesis because you pass the argument Byval (see GetVersionVar2() down here).
So there's still an extra temporary variable that is created by VB at call time. It takes the address returned by VarPtr(), but as it's then passed byval the same and correct target Variant address is finally used in the DLL.
Tested in Access and Excel (both 2016).
PB:
Code: Select all
EnableExplicit
DisableDebugger
#APP_VERSION = "1.0.0"
Threaded *strGetVersion
ProcedureDLL.i GetVersion()
If *strGetVersion
SysFreeString_(*strGetVersion)
EndIf
*strGetVersion = SysAllocString_("This is Version " + #APP_VERSION)
ProcedureReturn *strGetVersion
EndProcedure
ProcedureDLL.i GetVersionVariant(*text.variant) ; <- parameter text Byref of type variant
If *text
MessageRequester("GetVersionVariant in DLL", "Variant address="+Hex(*text))
VariantClear_(*text)
*text\vt = #VT_BSTR
*text\bstrVal = SysAllocString_("This is Version " + #APP_VERSION)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
VB/A:
Code: Select all
Private Declare PtrSafe Function GetVersion Lib "ReturnStringTest.dll" () As String
Private Declare PtrSafe Function GetVersionVariant Lib "ReturnStringTest.dll" (ByRef text As Variant) As Long
Private Declare PtrSafe Function GetVersionVariant2 Lib "ReturnStringTest.dll" _
Alias "GetVersionVariant" (ByVal pVariant As LongPtr) As Long
Sub Main()
'Sample in Access VBA, change directory where DLL is or place DLL in PATH
Dim sVersion As String
ChDir CurrentProject.Path 'Access only, full dll path or dll in PATH for Excel
Dim text As Variant
Dim pVariant As LongPtr
pVariant = VarPtr(text)
Debug.Print "VarPtr(text)="; Hex$(pVariant)
Call GetVersionVariant(text)
Debug.Print text
Call GetVersionVariant2(pVariant)
Debug.Print text
'NO temporary var problem with byval
GetVersionVariant2 VarPtr(text) 'OK
GetVersionVariant2 (VarPtr(text)) 'OK too, same address, but hidden temp var
End Sub