Search code examples
c#godllcgo

Calling function from Go in C#


I'm trying to make a .dll file from Golang to be used in a C# script. However, I can't make a simple example work.

Here is my Go code:

package main

import (
    "C"
    "fmt"
)

func main() {}

//export Test 
func Test(str *C.char) {
    fmt.Println("Hello from within Go")
    fmt.Println(fmt.Sprintf("A message from Go: %s", C.GoString(str)))
}

Here is my C# code:

using System;
using System.Runtime.InteropServices;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello");
            GoFunctions.Test("world");
            Console.WriteLine("Goodbye.");
        }
    }


    static class GoFunctions
    {
    [DllImport(@<path to test.dll>, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
    public static extern void Test(string str);
    }
}

I'm building the dll from:

go build -buildmode=c-shared -o test.dll <path to go file>

The output is

Hello
Hello from within Go
A message from Go: w

panic: runtime error: growslice: cap out of range

Solution

  • It works with byte[] instead of string, that is, with the following C# code:

    using System;
    using System.Runtime.InteropServices;
    
    namespace test
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello");
                GoFunctions.Test(System.Text.Encoding.UTF8.GetBytes("world"));
                Console.WriteLine("Goodbye.");
            }
        }
    
    
        static class GoFunctions
        {
        [DllImport(@<path to test.dll>, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern void Test(byte[] str);
        }
    }
    

    I'm not sure why string does not work here though.