String interchange between C# to and ANSI C DLL

How to send and receive a string between C# and C.

Recently we had some problems interfacing a C# code with a C ( especially MinGW ) DLL. The main problem was that we needed to interchange strings, send ans received from both directions.

Sending a registry entry from C# to C

C

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

namespace CODE
{
    public unsafe class Connector
    {
        private string PathKey = "Path";
        // needs to be constant...
        private const string PathToCDLL = @"C:pathtocdll";

        public void InitPath()
        {
            string Path = new Globals().getRegistryEntry(this.PathKey);
            // string characters are 2 bytes long in C#, C needs 1 byte chars:
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] path = encoding.GetBytes( Path );
            init_path_c(path);
        }

        [DllImport(PathToCDLL, EntryPoint = "init_path", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        private static extern void init_path_c([MarshalAs(UnmanagedType.LPArray)] byte[] Path );
    }
}

C

char* global_path;
void init_path( char* path )
{
      global_path = path;
}

Receiving a string in C# from C

CS

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

namespace CODE
{
    public unsafe class Connector
    {
        public string getCString()
        {
            IntPtr strPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
            get_c_string(strPtr);
            return Marshal.PtrToStringAnsi(strPtr);
        }

        [DllImport(PathToCDLL, EntryPoint = "c_string", ExactSpelling = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        private static extern void get_c_string( IntPtr Path );

    }
}

C

#include <string.h>

void c_string( char* path )
{  
  char* str = "This is a test string";
  strcpy ( path, str );
}

(Oh, by the way: this entry was written by Peter Molnar, and originally posted on petermolnar dot net.)