Notifications
Clear all

[Closed] SendMessage and Marshal.String

I just found that it’s possible to send some string allocated in unmanaged memory.
How safe is that compared to second example?

fn showCalltip mxsehwnd offsetPos calltipText = (
	
	marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
	ptr = marshal.StringToHGlobalUni calltipText

	windows.SendMessage mxsehwnd 0x0898 offsetPos ptr 
		
)
dll_MXSEshowCalltip = (

	source = ""
	source += "using System;
"
	source += "using System.Text;
"
	source += "using System.Runtime.InteropServices;
"
	source += "class csharp_showCalltip
"
	source += "{
"
	source += "[DllImport(\"user32.dll\", CharSet=CharSet.Auto, SetLastError=true)]
"
	source += "public static extern int SendMessage(Int32 hWnd, int wMsg, int wParam, string lParam);
"
	source += "static public void showCalltip( Int32 hWnd, int pos, string text ){
"
	source += "SendMessage( hWnd, 0x0898, pos, text );
"
	source += "}}
"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
								
	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
	compilerResults.CompiledAssembly.CreateInstance "csharp_showCalltip"					

)
4 Replies
 lo1

The first will leak memory if you don’t manually free it. The second will not.

Thanks, Rotem.
I couldn’t notice any ‘leak’ after several thousands of function calls, but spy++ shows clearly that every call a new memory address is sent. Either my test string is too short to notice that leakage or it’s that unnoticeable.
Does dotnet gc will free it after some time or freeing it manually is my only option?

 lo1

GC will not free it because it’s not managed memory. You need to call the corresponding free function after use.

There’s not much point in using this if you can use the managed method. The only scenario I can think of is if you need to call the pinvoke method many times with the same string and you’ve identified it as a performance bottleneck. Even then I would test to see if it makes a difference.

I’ll stick with the compiled version then.
Thx