Skip to content

c-shared (DLL) library created for Windows fails to initialize runtime when called from C# application #26714

@rickfillion

Description

@rickfillion

What version of Go are you using (go version)?

1.10 darwin/amd64
Also tried 1.10.2, 1.10.3, 1.11beta2

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/rfillion/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/rfillion/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/sw/bykzdlq92_nfwpxflx4m_8jm0000gp/T/go-build405501066=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I have a very very simple main.go file:

package main

import "C"
import "fmt"

func main() {
	fmt.Println(Bar())
	fmt.Println(Bar2())	
	return 
}

//export Bar
func Bar() C.long {
	fmt.Println("GOT HERE")
	return 54
}

//export Bar2
func Bar2() *C.char {
	return C.CString("Hello World From Go!")
}

I'm cross-compiling it as a DLL for Windows/x86 from my AMD64 MacOS 10.13 device via:

GOOS=windows GOARCH=386 CGO_ENABLED=1 CC=i686-w64-mingw32-gcc go build -buildmode=c-shared -o main.dll main.go

Then I'm attempting to make using of this DLL from within a C# application compiled with Visual Studios 2017 on Windows 10. Complete source for this application is:

using System;
using System.Runtime.InteropServices;

namespace x86Hullo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Huuullllloooo!!");
            Console.WriteLine("Before Bar");
            GoFunctions.Bar();
            Console.WriteLine("After Bar");
            Console.WriteLine("Goodbye.");
        }
    }


    static class GoFunctions
    {
        [DllImport(@"C:\Users\rfillion\main.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern long Bar();
    }
}

What did you expect to see?

I would expect to see console output that looks like:

Huuullllloooo!!
Before Bar
GOT HERE
After Bar
Goodbye.

What did you see instead?

Huuullllloooo!!
Before Bar

The process is then hung. If I pause the process in the debugger I see the following:
image

Looking at the dissassembled version of the DLL, it seems that it's stuck in _cgo_wait_runtime_init_done's while true loop checking whether the runtime is up.

When I compile this same go file as a unix .so file and link it with a C program on the Mac everything works exactly as expected.

Is this expected to work? It was my understanding that as of Go 1.10 this was supposed to work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Windows

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions