wails icon indicating copy to clipboard operation
wails copied to clipboard

启用CGO 之后功能不正常

Open bert1020 opened this issue 6 months ago • 4 comments

Description

我启用cgo打包用到的命令 $env:CGO_ENABLED="1";wails build -platform windows/amd64 -clean -o daliTools.exe 这种情况下,打包完成dll没有复制到bin目录下,我手动复制dll到bin目录下,虽然log.Fatal没有报错 同样代码什么都没有改动 ,打包命令仅仅加个-debug ,程序就正常了,能正常访问dll里面的接口,也有信息返回,但是去掉-debug就不行了,是不是正常打包去掉了什么正是我需要的

To Reproduce

1.启用cgo 2.loadDll 3.调用里面的方法

Expected behaviour

dll方法里面返回信息

Screenshots

Image

	dll, err := syscall.LoadDLL("Knx.Sdk.dll")
	if err != nil {
		log.Fatal("DLL 加载失败:", err)
		return
	}
	sdkDll = dll
	// 获取创建隔离线程函数
	createIsolate, err := dll.FindProc("graal_create_isolate")
	if err != nil {
		fmt.Printf("查找 graal_create_isolate 函数失败: %v\n", err)
		return
	}

	// 创建参数结构体
	params := &GraalCreateIsolateParams{
		Version: 4, // 当前版本为4
	}

	// 创建指针用于接收结果
	var isolate *GraalIsolate

	// 调用创建隔离线程函数
	ret, _, err := createIsolate.Call(
		uintptr(unsafe.Pointer(params)),
		uintptr(unsafe.Pointer(&isolate)),
		uintptr(unsafe.Pointer(&thread)),
	)

	if ret != 0 {
		fmt.Printf("创建隔离线程失败: %v\n", err)
		return
	}
	fmt.Printf("隔离线程创建成功\n")
}

### Attempted Fixes

_No response_

### System Details

```shell
# Wails
Version | v2.10.1


# System
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| OS           | Windows 10 Pro                                                                                   |
| Version      | 2009 (Build: 26100)                                                                              |
| ID           | 24H2                                                                                             |
| Go Version   | go1.24.1                                                                                         |
| Platform     | windows                                                                                          |
| Architecture | amd64                                                                                            |
| CPU          | Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz                                                        |
| GPU 1        | OrayIddDriver Device (Shanghai Best Oray Information Technology Co., Ltd.) - Driver: 17.1.58.818 |
| GPU 2        | Intel(R) HD Graphics 630 (Intel Corporation) - Driver: 24.20.100.6287                            |
| GPU 3        | NVIDIA GeForce GTX 1050 Ti with Max-Q Design (NVIDIA) - Driver: 22.21.13.8554                    |
| Memory       | 32GB                                                                                             |
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌───────────────────────────────────────────────────────┐
| Dependency | Package Name | Status    | Version       |
| WebView2   | N/A          | Installed | 136.0.3240.92 |
| Nodejs     | N/A          | Installed | 22.14.0       |
| npm        | N/A          | Installed | 10.9.2        |
| *upx       | N/A          | Available |               |
| *nsis      | N/A          | Available |               |
|                                                       |
└─────────────── * - Optional Dependency ───────────────┘

# Diagnosis
Optional package(s) installation details:
  - upx : Available at https://upx.github.io/
  - nsis : More info at https://wails.io/docs/guides/windows-installer/

Additional context

No response

bert1020 avatar May 28 '25 09:05 bert1020

👋 Thanks for reporting this issue! To help us investigate, could you please:

  1. Add the output of wails doctor if not already included
  2. Provide clear steps to reproduce the issue
  3. If possible, create a minimal reproduction of the issue

This will help us resolve your issue much faster. Thank you!

github-actions[bot] avatar May 28 '25 09:05 github-actions[bot]

👋 Thanks for reporting this issue! To help us investigate, could you please:

  1. Add the output of wails doctor if not already included
  2. Provide clear steps to reproduce the issue
  3. If possible, create a minimal reproduction of the issue

This will help us resolve your issue much faster. Thank you!

github-actions[bot] avatar May 28 '25 09:05 github-actions[bot]

通过一步步写文件测试发现是fmt.Printf("调用 SearchKnxServers 函数失败: %v\n", err1)报错了,报的错误信息为The handle is invalid. 能帮我看下是哪方面的问题吗?


/*
#include <stdlib.h>
*/
import "C"
import (
	"errors"
	"fmt"
	"log"
	"syscall"
	"unsafe"
)

// GraalIsolate 定义隔离线程相关结构体
type GraalIsolate struct{}
type GraalIsolateThread struct{}

// GraalCreateIsolateParams 创建隔离线程的参数结构体
type GraalCreateIsolateParams struct {
	Version                         int32   // 结构体版本
	ReservedAddressSpaceSize        uintptr // 保留地址空间大小
	AuxiliaryImagePath              *byte   // 辅助镜像路径
	AuxiliaryImageReservedSpaceSize uintptr // 辅助镜像保留空间大小
	Reserved1                       int32   // 内部使用
	Reserved2                       **byte  // 内部使用
	Pkey                            int32   // 隔离保护键或域
	Reserved3                       byte    // 内部使用
	Reserved4                       byte    // 内部使用
}

var sdkDll *syscall.DLL
var searchKnxServersProc *syscall.Proc
var thread *GraalIsolateThread

func DestoryDll() {
	sdkDll.Release()
}
func InitSdkDll() {
	dll, err := syscall.LoadDLL("Knx.Sdk.dll")
	if err != nil {
		log.Fatal("DLL 加载失败:", err)
		return
	}
	sdkDll = dll
	// 获取创建隔离线程函数
	createIsolate, err := dll.FindProc("graal_create_isolate")
	if err != nil {
		fmt.Printf("查找 graal_create_isolate 函数失败: %v\n", err)
		return
	}

	// 创建参数结构体
	params := &GraalCreateIsolateParams{
		Version: 4, // 当前版本为4
	}

	// 创建指针用于接收结果
	var isolate *GraalIsolate

	// 调用创建隔离线程函数
	ret, _, err := createIsolate.Call(
		uintptr(unsafe.Pointer(params)),
		uintptr(unsafe.Pointer(&isolate)),
		uintptr(unsafe.Pointer(&thread)),
	)

	if ret != 0 {
		fmt.Printf("创建隔离线程失败: %v\n", err)
		return
	}
	fmt.Printf("隔离线程创建成功\n")
}
func SearchServers() (string, error) {
	if searchKnxServersProc == nil {
		proc, err := sdkDll.FindProc("SearchKnxServers")
		if err != nil {
			fmt.Printf("查找 SearchKnxServers 函数失败: %v\n", err)
			return "", err
		}
		searchKnxServersProc = proc
	}
	// 调用函数获取结果
	result, _, err1 := searchKnxServersProc.Call(uintptr(unsafe.Pointer(thread)))
	if !errors.Is(err1, syscall.Errno(0)) {
		fmt.Printf("调用 SearchKnxServers 函数失败: %v\n", err1)
		return "", err1
	}
	// 将结果转换为 Go 字符串
	jsonStr := C.GoString((*C.char)(unsafe.Pointer(result)))
	return jsonStr, nil
}

bert1020 avatar May 28 '25 10:05 bert1020

InitSdkDll 里面不会报错 ,也能获取到SearchKnxServers 返回的信息, 调用完InitSdkDll 再SearchServers里面就会报错,但是wails dev 和打包的时候加上-debug命令又正常了


/*
#include <stdlib.h>
*/
import "C"
import (
	"errors"
	"fmt"
	"log"
	"os"
	"syscall"
	"unsafe"
)

// GraalIsolate 定义隔离线程相关结构体
type GraalIsolate struct{}
type GraalIsolateThread struct{}

// GraalCreateIsolateParams 创建隔离线程的参数结构体
type GraalCreateIsolateParams struct {
	Version                         int32   // 结构体版本
	ReservedAddressSpaceSize        uintptr // 保留地址空间大小
	AuxiliaryImagePath              *byte   // 辅助镜像路径
	AuxiliaryImageReservedSpaceSize uintptr // 辅助镜像保留空间大小
	Reserved1                       int32   // 内部使用
	Reserved2                       **byte  // 内部使用
	Pkey                            int32   // 隔离保护键或域
	Reserved3                       byte    // 内部使用
	Reserved4                       byte    // 内部使用
}

var sdkDll *syscall.DLL
var searchKnxServersProc *syscall.Proc
var thread *GraalIsolateThread

func DestoryDll() {
	sdkDll.Release()
}
func InitSdkDll() {
	dll, err := syscall.LoadDLL("Knx.Sdk.dll")
	if err != nil {
		log.Fatal("DLL 加载失败:", err)
		return
	}
	sdkDll = dll
	// 获取创建隔离线程函数
	createIsolate, err := dll.FindProc("graal_create_isolate")
	if err != nil {
		fmt.Printf("查找 graal_create_isolate 函数失败: %v\n", err)
		return
	}

	// 创建参数结构体
	params := &GraalCreateIsolateParams{
		Version: 4, // 当前版本为4
	}

	// 创建指针用于接收结果
	var isolate *GraalIsolate

	// 调用创建隔离线程函数
	ret, _, err := createIsolate.Call(
		uintptr(unsafe.Pointer(params)),
		uintptr(unsafe.Pointer(&isolate)),
		uintptr(unsafe.Pointer(&thread)),
	)

	if ret != 0 {
		fmt.Printf("创建隔离线程失败: %v\n", err)
		return
	}
	fmt.Printf("隔离线程创建成功\n")

	proc, err := sdkDll.FindProc("SearchKnxServers")
	if err != nil {
		data1 := "查找 SearchKnxServers 函数失败"
		_ = os.WriteFile("output.txt", []byte(data1), 0644)
		fmt.Printf("查找 SearchKnxServers 函数失败: %v\n", err)
	}

	// 调用函数获取结果
	result, _, err1 := proc.Call(uintptr(unsafe.Pointer(thread)))
	if !errors.Is(err1, syscall.Errno(0)) {
		data2 := "调用 SearchKnxServers 函数失败" + err1.Error()
		_ = os.WriteFile("output.txt", []byte(data2), 0644)
		fmt.Printf("调用 SearchKnxServers 函数失败: %v\n", err1)
	}
	// 将结果转换为 Go 字符串
	jsonStr := C.GoString((*C.char)(unsafe.Pointer(result)))
	data3 := "调用 SearchKnxServers 函数返回信息:" + jsonStr
	_ = os.WriteFile("output.txt", []byte(data3), 0644)
}
func SearchServers() (string, error) {

	proc, err := sdkDll.FindProc("SearchKnxServers")
	if err != nil {
		fmt.Printf("查找 SearchKnxServers 函数失败: %v\n", err)
		return "", err
	}

	// 调用函数获取结果
	result, _, err1 := proc.Call(uintptr(unsafe.Pointer(thread)))
	if !errors.Is(err1, syscall.Errno(0)) {
		fmt.Printf("调用 SearchKnxServers 函数失败: %v\n", err1)
		return "", err1
	}
	// 将结果转换为 Go 字符串
	jsonStr := C.GoString((*C.char)(unsafe.Pointer(result)))
	return jsonStr, nil
}

bert1020 avatar May 28 '25 10:05 bert1020

经过测试下来,如果打成正式包 就不能把*syscall.DLL单独提取出来,存到内存中,不然就报错需要打成debug包 var sdkDll *syscall.DLL var searchKnxServersProc *syscall.Proc var thread *GraalIsolateThread

bert1020 avatar Jun 03 '25 02:06 bert1020

经过测试,应该不是wails的问题,但我不知道怎么解决 我测试手动构建,我只要加上-H windowsgui,就不行了,应该是GRAAL VM编译出来的DLL依赖于黑窗口 go build -tags desktop,production -gcflags "all=-N -l" -ldflags "-H windowsgui"

bert1020 avatar Jun 03 '25 06:06 bert1020