Weird marshalling problem

  • Thread starter Thread starter Dragon
  • Start date Start date
D

Dragon

Hello,

This is the code:

~
Option Strict On
Imports System
Imports System.Windows.Forms
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Class Test
Inherits Form

Friend Declare Auto Function GetWindowText Lib "user32.dll" ( _
ByVal hWnd as IntPtr, _
<MarshalAs(UnmanagedType.LPTStr), [In](), Out()> ByVal lpString As
String, _
ByVal nMaxCount as Integer _
) As Integer

Protected Overrides Sub OnLoad(e as EventArgs)
MyBase.OnLoad(e)
Text() = "All right!"
Dim tempStr As New String(chr(0),256)
Dim Result as Integer = GetWindowText(Me.Handle, tempStr,
tempStr.Length)
MessageBox.Show(Result.ToString & " " tempStr)
End Sub

<STAThread()> Shared Sub Main()
Application.Run(New Test)
End Sub
End Class
~

I expected it to msgbox "10 All right!" and it did it. In Windows XP.
But... testing it in Windows 98 gave strange result: "10 ". For some
curious reason string wasn't marshalled back, even though I included
OutAttribute.
However when I removed all attributes, it worked fine it both OS'es.
What's the difference? Is it documented or bug?

TIA
Roman
 
use ByRef. ie.:


Friend Declare Auto Function GetWindowText Lib "user32.dll" ( _
ByVal hWnd as IntPtr, _
<MarshalAs(UnmanagedType.LPTStr)> ByRef lpString As String, _
ByVal nMaxCount as Integer ) As Integer
 
Hi,

Dragon said:
Hello,

This is the code:

~
Option Strict On
Imports System
Imports System.Windows.Forms
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Class Test
Inherits Form

Friend Declare Auto Function GetWindowText Lib "user32.dll" ( _
ByVal hWnd as IntPtr, _
<MarshalAs(UnmanagedType.LPTStr), [In](), Out()> ByVal lpString As
String, _
ByVal nMaxCount as Integer _
) As Integer

Protected Overrides Sub OnLoad(e as EventArgs)
MyBase.OnLoad(e)
Text() = "All right!"
Dim tempStr As New String(chr(0),256)
Dim Result as Integer = GetWindowText(Me.Handle, tempStr,
tempStr.Length)
MessageBox.Show(Result.ToString & " " tempStr)
End Sub

<STAThread()> Shared Sub Main()
Application.Run(New Test)
End Sub
End Class


You should be using a StringBuilder if native code changes the string. See

http://msdn.microsoft.com/library/d...ide/html/cpcondefaultmarshalingforstrings.asp

scroll to the bottom : "Fixed-Length String Buffers"


HTH,
Greetings
 
Ah yes. GetWindowText just plonks the text into an already existing buffer,
however, your marshalling attributes were probably causing it some confusion
as you were technically trying to marshal it as .... actually I have no
idea. It works. Stop whinging ;)
 
Back
Top