c - 如何解决 mingw(或 mingw-w64)gcc 中缺少 InitOnceExecuteOnce?

标签 c winapi mingw opencl

我正在尝试构建 OpenCL ICD Loader在 mingw gcc 中——使用 mingw-w64 没问题,只是我已经安装了 mingw。我不使用 Visual Studio - 我不讨厌它,我知道有免费版本,只是我用的不是它。

OpenCL ICD 加载器不在 mingw gcc 中构建。主要原因是缺少对 DirectX 10 和 DirectX 11 的支持。但是 ICD Loader 所做的只是获取一个调度表(大概来自 OpenCL 驱动程序/它加载的任何内容)并提供通过该调度表调用的函数。对 icd_dispatch.hicd_dispatch.c 中条件编译的一些小改动可以省略相关函数并删除依赖项(Linux 构建已经这样做),并且实际上看起来这在过去可能已经得到支持 - 如果包含相关 header ,则已经定义了预处理器符号 cl_khr_d3d10_sharingcl_khr_d3d11_sharing ,它们只是没有被有条件地使用编译相关的代码块。

就是这样,并告诉代码首先省略 DirectX10 和 DirectX11 功能(我只是注释掉了几个头文件包含,尽管这显然不是真正的解决方案)。但是还有一个问题......

文件 icd_windows.c 使用 Windows API 函数 InitOnceExecuteOnce - MSDN docs here . mingw(我认为 mingw-w64)不支持此函数 - Kernel32.dll 的 def 文件列出了它,但函数和相关标识符均未列出 INIT_ONCEINIT_ONCE_STATIC_INITPINIT_ONCE由头文件提供。

IMO 的 MSDN 文档对此解释得不是很好。它可能不是必需的(在 Vista 之前它甚至不存在)并且它与 DLL 的安全初始化有关,大概是在多线程上下文中。

不幸的是,如果我不真正理解它的作用,那么我就无法实现它不存在的解决方法。

显然,此 Windows API 并非特定于 OpenCL,因此推测这是其他人在其他项目中遇到的问题。那么是否有针对此问题的标准解决方法?

或者失败了,有人可以解释一下“同步一次性初始化”的具体含义吗?抱歉,如果这是一个愚蠢的问题,我对多线程没有太多经验,我认为一次性初始化就是这样,无论同步还是异步——只要第二个线程不能重新进入初始化,您不想再次初始化,因此无论如何同步和异步都没有什么可做的。

或者这是否意味着如果另一个线程试图调用初始化,它会等待已经运行的初始化完成,然后才会失败(或者可能成功而无需重新进行初始化)?


我不确定 opencl 标签是否合适,因为上下文决定包含它,如果有误,我深表歉意。

最佳答案

我遇到了同样的问题。您必须在 icd_windows.c 的开头添加以下行,在所有 #includes 之前:

#define _WIN32_WINNT 0x0600

这有助于缺少 InitOnceExecuteOnce 声明。我还必须修改 CMakeLists.txt,将第 22 行中负责链接 libOpenCL 的 SHARED 替换为 STATIC。我这样做是因为链接器提示缺少 ld 库:

add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES})

完成这两件事后,我在构建子目录中得到了 libOpenCL.a。编译继续并因其他错误而失败,但我忽略了这一点。我使用创建的库并成功地使用它来构建简单的 OpenCL 应用程序,其中列出了所有可用的平台、设备及其详细信息。

关于c - 如何解决 mingw(或 mingw-w64)gcc 中缺少 InitOnceExecuteOnce?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39179957/

相关文章:

c - 如何在不使用 select() 的情况下在特定套接字和特定端口上超时?

c++ - 从文件中读取随机字符串时出错

c - C , DOS 中的串行编程

c - typedef 固定长度数组 -> 自动扩展大小?

c - MinGW编译器进程返回进程返回0xC00000fd

mingw - 如何卸载msys2?

c - nmake 相当于 mingw 命令

c - 使用Lex统计字符串出现次数,makefile可能出现的问题

c++ - 在 MFC 应用程序中未调用重叠的 WSARecv() 回调

c - 枚举桌面上的所有窗口句柄