Question

I'm trying to use a function from a Fortran library. The function is supposed to return a string. If I use this

Friend Declare Ansi Sub LaA_LabelGet Lib "V3Mat.dll" (ByRef hLaA As IntPtr, ByVal iRegion As Integer, ByVal cLabel As String, ByVal intLabelLen As Integer)

statement it works fine, if I use

<DllImport("V3Mat.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Ansi)>
Friend Sub LaA_LabelGet(ByRef hLaA As IntPtr, ByVal iRegion As Integer, ByVal cLabel As String, ByVal intLabelLen As Integer)
End Sub

the cLabel is always blank.

Can anyone please point out the difference between the two. I'd rather use the second definition as it allows me to set the library to use by using a constant.

Was it helpful?

Solution

The Declare statement is legacy syntax that was adopted in VB.NET to work the way it did back in the VB6 days. The one thing it does that matters in your case is that it allows native code to write into the string. Like it was possible back in VB6. Which is entirely invalid in .NET, strings are immutable.

The exact equivalent in the <DllImport> declaration would be <MarshalAs(UnmanagedType.VBByRefStr)> ByRef cLabel As String

The better solution is to declare the argument as ByVal cLabel As StringBuilder and pass a properly initialized StringBuilder object with a sufficient Capacity. And use its ToString() method afterwards to obtain the returned string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top