Weird marshalling problem

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
 
R

Robin Tucker

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
 
B

Bart Mermuys

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
 
R

Robin Tucker

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 ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top