Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
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.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace FileCopyTest
{
    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");
        }
    }
}
Posted

Assigning a char pointer like you did doesn't copy a string. And you don't need unsafe code to convert strings:
static void Main(string[] args)
{
    IntPtr ptr = Marshal.AllocHGlobal(255);
    Error(ptr);
    string msg = Marshal.PtrToStringAnsi(ptr);
    Console.Write(msg);
    Marshal.FreeHGlobal(ptr);
}
public static void Error(IntPtr ptr)
{
    string error = "This is just testing ... Again Testing";

    //converting the source string to a byte array
    IntPtr ptr2 = Marshal.StringToHGlobalAnsi(error);
    byte[] ptr2Bytes = new byte[error.Length + 1];
    Marshal.Copy(ptr2, ptr2Bytes, 0, ptr2Bytes.Length);
    Marshal.FreeHGlobal(ptr2);

    //copying the byte array to the destination pointer
    Marshal.Copy(ptr2Bytes, 0, ptr, ptr2Bytes.Length);
}
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 23-Feb-11 22:15pm    
Olivier, very good, my 5.

The whole code might be is pointless.
It is a demonstration of how to marshal PChar as IntPtr to string.
But we don't see how this pointer is obtained. In this sample it is obtained from the test funcion Error. In real life is can come from some function linked via P/Invoke, but the parameters can be converted at the declaration using Marshal attributes instead.

@Member 4581741171: what will you say? What is that unmanaged function you need to get string from? Maybe you can show how to marshal in P/Invoke without your code...

--SA

--SA
Olivier Levrey 24-Feb-11 4:18am    
Thanks SA. You're right, this example is not useful on its own. Just to desmonstrate how to convert strings to pointers and back using Marhal class.
I must admit that when I started working with P/Invoke and marshaling a few years ago, I often had headhaches (especially when dealing with structures and array of structures)... Now we can find lots of good articles about it :)
Sergey Alexandrovich Kryukov 24-Feb-11 13:23pm    
Well, as to me, I had very little problems. There are exotic cases (sometimes when the author if managed code abuse the technology even from the stand point of the unmanaged)...
--SA
worked for me ... -> in console window I got the "This is .... " message.
 
Share this answer
 
Now uncomment //ShrinkError(errMsg);
and comment errMsg = (char*)Marshal.StringToHGlobalAnsi("This is just testing ... Again Testing");
and execute.
Expected o/p is same but getting different o/p.

ShrinkError method is Error method here.
 
Share this answer
 
v2
Comments
Olivier Levrey 23-Feb-11 10:42am    
don't post answers to reply to others. Use comments.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900