10 Replies - 2452 Views - Last Post: 23 February 2011 - 01:34 PM Rate Topic: ****- 1 Votes

#1 chintan_1671   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 46
  • Joined: 22-December 08

Marshaling Char pointer Problem

Posted 23 February 2011 - 07:56 AM

I am facing a small problem. Something i might have mis understood.
If u see the code without using a function if i print the message then i am getting proper output. But after i create Error function and print message from main function it is creating some problem.
I am not sure is to why this is the case.

Help would be appreciated.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace Test
{
    class Program
    {
        unsafe static void Main(string[] args)
        {
            char* errMsg = (char*)Marshal.AllocHGlobal(255);
            //ShrinkError(errMsg);
            errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing");
            string msg = Marshal.PtrToStringAnsi((IntPtr)errMsg);
            Console.Write(msg);
            Marshal.FreeHGlobal((IntPtr)errMsg);
        }

        unsafe public static void Error(char* msg)
        {
           msg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing\n");
        }
    }
}


Is This A Good Question/Topic? 0
  • +

Replies To: Marshaling Char pointer Problem

#2 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:03 AM

We have no idea what you consider "proper output", nor have you told us was "creating some problem" means?

Do you get an error message? Output not as expected?

What *is* 'proper output' that you would expect from this?
Was This Post Helpful? 0
  • +
  • -

#3 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:15 AM

What is the real purpose of this? Do you have a solid reason for using unsafe and unmanaged memory?
If you are just trying to convert a string to ANSI there are better ways to do that.
http://msdn.microsof...ng.convert.aspx
Was This Post Helpful? 0
  • +
  • -

#4 chintan_1671   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 46
  • Joined: 22-December 08

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:23 AM

View PosttlhIn`toq, on 23 February 2011 - 08:03 AM, said:

We have no idea what you consider "proper output", nor have you told us was "creating some problem" means?

Do you get an error message? Output not as expected?

What *is* 'proper output' that you would expect from this?


What i need to do is that need to store message at some memory location and use that message at different places. I need to use pointers because the application needed to be backward compatible.


If u run my code u will get "This is just testing ... Again Testing" as output.
Now after commenting the line "errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing");" and uncomment "//ShrinkError(errMsg);" the expected output should be same but getting different output.
Was This Post Helpful? 0
  • +
  • -

#5 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:34 AM

View Postchintan_1671, on 23 February 2011 - 09:23 AM, said:

If u run my code u will get "This is just testing ... Again Testing" as output.
Now after commenting the line "errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing");" and uncomment "//ShrinkError(errMsg);" the expected output should be same but getting different output.


How are any of us expected to do that when the code you provided doesn't have a ShrinkError method in it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace Test
{
    class Program
    {
        unsafe static void Main(string[] args)
        {
            char* errMsg = (char*)Marshal.AllocHGlobal(255);
            //ShrinkError(errMsg);
            errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing");
            string msg = Marshal.PtrToStringAnsi((IntPtr)errMsg);
            Console.Write(msg);
            Marshal.FreeHGlobal((IntPtr)errMsg);
        }

        unsafe public static void Error(char* msg)
        {
           msg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing\n");
        }
    }
}






Pull stop. Breathe. Pull yourself together. The copy the actual code you are using and paste it in here.
Was This Post Helpful? 0
  • +
  • -

#6 chintan_1671   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 46
  • Joined: 22-December 08

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:40 AM

Quote

Pull stop. Breathe. Pull yourself together. The copy the actual code you are using and paste it in here.


Sorry my bad. ShrinkError is Error Method in code. I am bad to pointers.

This post has been edited by chintan_1671: 23 February 2011 - 08:53 AM

Was This Post Helpful? 0
  • +
  • -

#7 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 08:55 AM

So here's how I do things like this.
I make a little app that has separate methods so I don't have to comment and re-run.
Textboxes so I don't hard code.

Attached Image

Type a message in the first textbox and click the one or two button to run the given method.
The result passed via that method appears in the bottom textbox. The names in the code should be self explanatory.

unsafe memory address pointers aren't my area of expertise but I believe you were making a new address in the method rather than passing a reference (pointer) to the address you had already made and allocated for this purpose. Just adding the ref designation seems to have fixed your code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            tbResult.Text = string.Empty; // Clear before making new
            One();
        }
        private void button2_Click(object sender, System.EventArgs e)
        {
            tbResult.Text = string.Empty; // Clear before making new
            Two();
        }

        private void btnClear_Click(object sender, System.EventArgs e)
        {
            tbResult.Text = string.Empty;
        }


        unsafe void One()
        {
            char* errMsg = (char*)Marshal.AllocHGlobal(255);
            errMsg = (char*)Marshal.StringToHGlobalAnsi(tbTestMessage.Text);
            string msg = Marshal.PtrToStringAnsi((IntPtr)errMsg);
            tbResult.Text = msg;
            Marshal.FreeHGlobal((IntPtr)errMsg);
        }
        unsafe void Two()
        {
            char* errMsg = (char*)Marshal.AllocHGlobal(255);
            ShrinkError(ref errMsg);
            string msg = Marshal.PtrToStringAnsi((IntPtr)errMsg);
            tbResult.Text = msg;
            Marshal.FreeHGlobal((IntPtr)errMsg);
        }


        unsafe public void ShrinkError(ref char* errMsg)
        {
            errMsg = (char*)Marshal.StringToHGlobalAnsi(tbTestMessage.Text);
        }
    }
}


Was This Post Helpful? 3
  • +
  • -

#8 chintan_1671   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 46
  • Joined: 22-December 08

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 09:33 AM

View PosttlhIn`toq, on 23 February 2011 - 08:55 AM, said:

So here's how I do things like this.
I make a little app that has separate methods so I don't have to comment and re-run.
Textboxes so I don't hard code.

Attachment refpassing.jpg

Type a message in the first textbox and click the one or two button to run the given method.
The result passed via that method appears in the bottom textbox. The names in the code should be self explanatory.

unsafe memory address pointers aren't my area of expertise but I believe you were making a new address in the method rather than passing a reference (pointer) to the address you had already made and allocated for this purpose. Just adding the ref designation seems to have fixed your code.


Ref solved my problem.
Thanks

But again i am not sure then why is this working without ref.
unsafe static void Main(string[] args)
        {
            char* errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing\n");
            ShrinkError(errMsg);
        }

        unsafe public static void ShrinkError(char* msg)
        {
           //errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing\n");
            string emsg = Marshal.PtrToStringAnsi((IntPtr)msg);
            Console.Write(emsg);
        }



Thanks

This post has been edited by chintan_1671: 23 February 2011 - 09:34 AM

Was This Post Helpful? 0
  • +
  • -

#9 JackOfAllTrades   User is offline

  • Saucy!
  • member icon

Reputation: 6259
  • View blog
  • Posts: 24,028
  • Joined: 23-August 08

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 09:49 AM

ref is not required because you're not returning the value to the caller, you're printing it out in the function.
Was This Post Helpful? 0
  • +
  • -

#10 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6537
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 09:59 AM

It works in the first use without REF because it is the same char* that you created.
But when you use it as a parameter to the ShrinkError method a new char* is created to hold that parameter. Thus your response is being held in the new char* created in the ShrinkError method, not in the char* you created in main(). They are two different variables and thus two different addresses. As long as you use the new variable within the scope of the method you are fine. But when you try to use the old variable thinking it has been updated by the method, that's when your issue arrises.
Was This Post Helpful? 3
  • +
  • -

#11 chintan_1671   User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 46
  • Joined: 22-December 08

Re: Marshaling Char pointer Problem

Posted 23 February 2011 - 01:34 PM

That makes sense.
Thanks

View PosttlhIn`toq, on 23 February 2011 - 09:59 AM, said:

It works in the first use without REF because it is the same char* that you created.
But when you use it as a parameter to the ShrinkError method a new char* is created to hold that parameter. Thus your response is being held in the new char* created in the ShrinkError method, not in the char* you created in main(). They are two different variables and thus two different addresses. As long as you use the new variable within the scope of the method you are fine. But when you try to use the old variable thinking it has been updated by the method, that's when your issue arrises.

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1