我正在试用一些使用CGO的Windows API函数.我有一个dockerfile,它使用命令构建二进制文件.我正在从Linux交叉编译Windows

    export PKG_CONFIG_PATH=/usr/x86_64-w64-mingw32/lib/pkgconfig;

    GOOS=windows GOARCH=amd64 CGO_ENABLED=1 \
        CGO_CFLAGS="-isystem /usr/x86_64-w64-mingw32/include -I/usr/x86_64-w64-mingw32/lib/pkgconfig -I/usr/x86_64-w64-mingw32/include \
        -I /usr/x86_64-w64-mingw32/include/gst-include/glib-2.0 \
        -I/usr/share/mingw-w64/include -I/usr/x86_64-w64-mingw32/include/gst-include/gstreamer-1.0" \
        CGO_LDFLAGS="-L/usr/x86_64-w64-mingw32/lib -L/usr/x86_64-w64-mingw32/lib/pkgconfig -Luser32" \
        CXX=x86_64-w64-mingw32-g++ \
        CC=x86_64-w64-mingw32-gcc go build -o bin/yaoe.exe main.go

我正在try 使用CGO编译以下代码

WINDOWS_helpers.h

#ifndef WINHELPERS_H
#define WINHELPERS_H

#include <windows.h>

LPCSTR wrapMAKEINTRESOURCEA(UINT_PTR i);
void CQueryDisplayConfig();

#endif // WINHELPERS_H

WINDOWS_helpers.c

#include "winhelpers_windows.h"

// wrapMAKEINTRESOURCEA wraps the MAKEINTRESOURCEA macro in a callable function
LPCSTR wrapMAKEINTRESOURCEA(UINT_PTR i) {
    return MAKEINTRESOURCEA(i);
}

void CQueryDisplayConfig() {
    UINT32 flags = 0x00000001;
    UINT32 numPathArrayElements;
    DISPLAYCONFIG_PATH_INFO *pathArray;
    UINT32 numModeInfoArrayElements;
    DISPLAYCONFIG_MODE_INFO *modeInfoArray;
    DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId;

    LONG queryReturn = QueryDisplayConfig(flags, &numPathArrayElements,
                                          &pathArray, &numModeInfoArrayElements,
                                          &modeInfoArray, &currentTopologyId);
}

这就是我如何将其包含在我的.go文件中

/*
#cgo CFLAGS: -I . -I/usr/x86_64-w64-mingw32/include
#cgo LDFLAGS: -L . -luser32 -l/usr/x86_64-w64-mingw32/lib
#include "winhelpers_windows.h"
*/
import "C"

我得到以下错误

winhelpers_windows.c: In function 'CQueryDisplayConfig':
winhelpers_windows.c:11:5: error: unknown type name 'DISPLAYCONFIG_PATH_INFO'
   11 |     DISPLAYCONFIG_PATH_INFO *pathArray;
      |     ^~~~~~~~~~~~~~~~~~~~~~~
winhelpers_windows.c:13:5: error: unknown type name 'DISPLAYCONFIG_MODE_INFO'
   13 |     DISPLAYCONFIG_MODE_INFO *modeInfoArray;
      |     ^~~~~~~~~~~~~~~~~~~~~~~
winhelpers_windows.c:14:5: error: unknown type name 'DISPLAYCONFIG_TOPOLOGY_ID'
   14 |     DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId;
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~
winhelpers_windows.c:16:24: warning: implicit declaration of function 'QueryDisplayConfig'; did you mean 'CQueryDisplayConfig'? [-Wimplicit-function-declaration]
   16 |     LONG queryReturn = QueryDisplayConfig(flags, &numPathArrayElements,
      |                        ^~~~~~~~~~~~~~~~~~
      |                        CQueryDisplayConfig

我已经判断了里面的/usr/x86_64-w64-mingw32/include个,而且typedef确实存在

yaoe@2a0b8c6ab378:/usr/x86_64-w64-mingw32/include$ grep -Rn DISPLAYCONFIG_TOPOLOGY_ID
wingdi.h:2255:  } DISPLAYCONFIG_TOPOLOGY_ID;
winuser.h:5621:  WINUSERAPI LONG WINAPI QueryDisplayConfig (UINT32 flags, UINT32 *numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 *numModeInfoArrayElements, DISPLAYCO
NFIG_MODE_INFO *modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId);

--------------------

yaoe@2a0b8c6ab378:/usr/x86_64-w64-mingw32/include$ grep -Rn DISPLAYCONFIG_PATH_INFO
wingdi.h:2238:  typedef struct DISPLAYCONFIG_PATH_INFO {
wingdi.h:2242:  } DISPLAYCONFIG_PATH_INFO;
winuser.h:5620:  WINUSERAPI LONG WINAPI SetDisplayConfig (UINT32 numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO *mo
deInfoArray, UINT32 flags);
winuser.h:5621:  WINUSERAPI LONG WINAPI QueryDisplayConfig (UINT32 flags, UINT32 *numPathArrayElements, DISPLAYCONFIG_PATH_INFO *pathArray, UINT32 *numModeInfoArrayElements, DISPLAYCO
NFIG_MODE_INFO *modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID *currentTopologyId);

类型定义位于windows.h包含的wingdi.h

不太确定哪里出了问题.微软文档说,简单地包括windows.h应该就足够了,而且确实包含这些typedef的所有其他头文件都包含在windows.h

推荐答案

正如@IInspectable提到的,该错误与Windows7中引入的SetDisplayConfigQueryDisplayConfig有关,由于我没有提供任何编译目标,所以MinGW找不到函数定义.

显式通知编译器针对Windows 10及更高版本进行编译已修复该问题

// Compile for windows 10 and above
#define _WIN32_WINNT_WIN10 0x0A00
#define WINVER 0x0A00

Go相关问答推荐

try 用GitHub操作中的release标签更新version. go文件,但失败了

追加一个字节数组的分配比2个字节数组的分配要少得多

创建服务时云运行触发器执行失败

由docker中的nginx提供的样式和图像在页面上不起作用

如何确定泛型类型在运行时是否可比较?

Go Build删除信息

按位移计算结果中的差异

Golang和Gin web框架在router.Run()之后执行代码

是否可以在调试期间在 VSCode 中预览 github.com/shopspring/decimal 值?

AWS Lambda 中的 Websocket URL 超时达到错误

从Go中的随机日期开始以天为单位获取时间

如何使用 Go 代理状态为 OK 的预检请求?

如何使用 Docker 引擎 SDK 和 Golang 运行 docker 挂载卷

未定义 protoc protoc-gen-go 时间戳

Golang模板无法访问embedFS中的文件

Go 并发、goroutine 同步和关闭通道

gorm 获取列名

Go Fyne 禁用 HSplit 调整大小?

在 Go 中将十六进制转换为带符号的 Int

Go:如何通过 GIN-Router 从 AWS S3 将文件作为二进制流发送到浏览器?