如何在mingw(或mingw-w64)gcc中解决缺少InitOnceExecuteOnce的问题?

时间:2016-08-27 10:14:53

标签: c winapi mingw opencl

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

OpenCL ICD Loader并不构建在mingw gcc中。主要原因是缺乏DirectX 10和DirectX 11支持。但是所有ICD Loader都会获得一个调度表(可能来自OpenCL驱动程序/无论它加载什么)并提供调用该调度表的函数。 icd_dispatch.hicd_dispatch.c中条件编译的一些细微更改可以省略相关函数并删除依赖关系(就像Linux版本中已经发生的那样),实际上看起来可能已经支持了过去 - 如果包含相关标头,那么已经定义了预处理器符号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_INIT和{ {1}}由头文件提供。

MSDN文档IMO不能很好地解释这一点。它可能是必不可少的(它在Vista之前甚至不存在),它与DLL的安全初始化有关,可能是在多线程环境中。

不幸的是,如果我真的不明白它的作用,那么我就无法实现一种解决方法,因为它不在那里。

显然,这个Windows API并不特定于OpenCL,因此可能这是其他人为其他项目遇到的问题。那么有一个标准的解决方法吗?

或者失败,有人可以解释特别是"同步一次性初始化"?很抱歉,如果这是一个愚蠢的问题,我没有多线程的经验,我认为一次性初始化就是这样,不管是同步还是异步 - 只要是第二个线程无法重新进入初始化状态,您不想再次初始化,因此无论如何都无法同步和异步进行。

或者它是否意味着如果另一个线程试图调用初始化,它将等待已经运行的初始化在它失败之前完成(或者可能在没有重新初始化的情况下成功)?

我不确定opencl标签是否合适,因为上下文而决定将其包括在内,如果这是错误的话,对不起。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。在所有#includes:

之前,你必须在icd_windows.c的开头添加以下行
#define _WIN32_WINNT 0x0600

这有助于遗漏InitOnceExecuteOnce声明。我还必须修改CMakeLists.txt,在第22行用SHARED替换STATIC,它负责链接libOpenCL。我这样做是因为链接器抱怨缺少ld lib:

add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES})

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