Skip to content

Crash if using import "C" in main file #47

@palindrom228

Description

@palindrom228

i'm trying to use your library in my project, and want to wrap it for my project with go layer that exports dll file, and in this case im getting null pointer in runtime

step to reproduce:

  1. use Windows arm64
  2. import "C" in main file
  3. start sing-box instance
  4. runtime crashes with no error

sing-box config: { "log": { "level": "warning", "timestamp": true }, "dns": { "servers": [ { "tag": "remote", "address": "8.8.8.8", "detour": "proxy" } ], "final": "remote" }, "inbounds": [ { "type": "tun", "tag": "tun-in", "interface_name": "singbox_tun", "address": [ "172.19.0.1/30" ], "mtu": 9000, "auto_route": true, "strict_route": false, "stack": "gvisor", "sniff": true } ], "outbounds": [ { "type": "socks", "tag": "proxy", "server": "127.0.0.1", "server_port": 10808, "version": "5" }, { "type": "direct", "tag": "direct" }, { "type": "dns", "tag": "dns_out" } ], "route": { "auto_detect_interface": true, "rules": [ { "outbound": "direct", "ip_is_private": true }, { "outbound": "dns_out", "port": [ 53 ], "process_name": [ "xray.exe", "cracker.exe" ] }, { "outbound": "direct", "process_name": [ "xray.exe", "cracker.exe" ] }, { "outbound": "proxy", "network": "tcp,udp" } ] } }

Wrapper package that calls from main


import (
	"context"
	"fmt"
	"os"
	"os/user"
	"strconv"

	"github.com/sagernet/sing-box/experimental/deprecated"
	"github.com/sagernet/sing-box/include"
	"github.com/sagernet/sing-box/log"
	"github.com/sagernet/sing-box/option"
	"github.com/sagernet/sing/common/json"
	"github.com/sagernet/sing/service"
	"github.com/sagernet/sing/service/filemanager"

	box "github.com/sagernet/sing-box"
)

var (
	globalCtx context.Context
)

type SingBox struct {
	tun *box.Box
}

func New(configJson string) (*SingBox, error) {
	configBytes := []byte(configJson)
	options, err := json.UnmarshalExtendedContext[option.Options](globalCtx, configBytes)
	if err != nil {
		return nil, fmt.Errorf("Error while parse options from config json : ", err.Error())
	}
	ctx, cancel := context.WithCancel(globalCtx)
	instance, err := box.New(box.Options{
		Context: ctx,
		Options: options,
	})
	if err != nil {
		cancel()
		return nil, fmt.Errorf("Error while creating sing box instance : ", err.Error())
	}
	return &SingBox{
		tun: instance,
	}, nil
}

func (s *SingBox) Run() error {
	err := s.tun.Start()
	if err != nil {
		return fmt.Errorf("Error while starting sing box : ", err)
	}
	return nil
}

func (s *SingBox) Stop() error {
	err := s.tun.Close()
	if err != nil {
		return fmt.Errorf("Error while stoping sing box : ", err)
	}
	return nil
}

func init() {
	globalCtx = context.Background()
	sudoUser := os.Getenv("SUDO_USER")
	sudoUID, _ := strconv.Atoi(os.Getenv("SUDO_UID"))
	sudoGID, _ := strconv.Atoi(os.Getenv("SUDO_GID"))
	if sudoUID == 0 && sudoGID == 0 && sudoUser != "" {
		sudoUserObject, _ := user.Lookup(sudoUser)
		if sudoUserObject != nil {
			sudoUID, _ = strconv.Atoi(sudoUserObject.Uid)
			sudoGID, _ = strconv.Atoi(sudoUserObject.Gid)
		}
	}
	if sudoUID > 0 && sudoGID > 0 {
		globalCtx = filemanager.WithDefault(globalCtx, "", "", sudoUID, sudoGID)
	}

	globalCtx = service.ContextWith(globalCtx, deprecated.NewStderrManager(log.StdLogger()))
	globalCtx = box.Context(globalCtx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry())
}```

i need to use it as library for KMM project, i'm not expirenced in go and cgo. thanks for answer in advance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions