我正在尝试在mingw gcc中创建OpenCL ICD Loader - 使用mingw-w64并没有问题,只是我已经安装了mingw。我不使用Visual Studio - 我不讨厌它,我知道有免费版本,这不是我正在使用的。如何解决在mingw(或mingw-w64)gcc中缺少InitOnceExecuteOnce?
OpenCL ICD Loader不会在mingw gcc中生成。主要原因是由于缺乏DirectX 10和DirectX 11支持。但是所有的ICD Loader所做的都是获取一个调度表(大概来自OpenCL驱动程序/不管它加载的是什么),并提供通过调度表调用的函数。 icd_dispatch.h
和icd_dispatch.c
中的条件编译的一些细微更改可以省略相关函数并删除相关性(因为Linux构建已经必须发生这种情况),实际上它看起来像过去可能已经支持的那样 - 有预处理器符号cl_khr_d3d10_sharing
和cl_khr_d3d11_sharing
已经定义,如果包含相关的头文件,它们只是没有被用来有条件地编译相关的代码块。
所以就是这样,并告诉代码首先忽略DirectX10和DirectX11功能(我刚刚注释掉了一些头文件,尽管这显然不是真正的解决方案)。但之后还有一个问题...
文件icd_windows.c
使用Windows API函数InitOnceExecuteOnce
- MSDN docs here。 mingw(我认为mingw-w64)不支持这个功能 - Kernel32.dll
的def文件列出了它,但函数和相关标识符INIT_ONCE
,INIT_ONCE_STATIC_INIT
和PINIT_ONCE
都由头文件提供。
MSDN文档IMO没有很好地解释这一点。它不是必需的(在Vista之前它甚至不存在),它与DLL的安全初始化有关,大概是在多线程环境中。
不幸的是,如果我真的不明白它的作用,那么我不能实施一种解决方法,因为它不在那里。
显然,这个Windows API并不特定于OpenCL,所以大概这是其他人遇到的其他项目的问题。那么有没有一个标准的解决方法呢?
或者失败了,有人可以解释什么是特别是由“同步一次性初始化”?对不起,如果这是一个愚蠢的问题,我没有太多的多线程经验,我认为一次初始化就是这样,不管是同步还是异步 - 只要第二个线程不能重新输入初始化,你不想再次初始化,所以没有什么可以同步或异步地完成。
或者这是否意味着如果另一个线程试图调用初始化,它会等待已经运行的初始化完成,然后它会失败(或者可能会成功而不重新执行初始化)?
我不确定opencl标记是否合适,因为上下文而决定包含它,如果那是错误的,那很抱歉。
只要我发布了这个问题,[此MSDN页面](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363808(v = vs.85).aspx)被移出我的盲点。哎呀。如果没有更好的答案出现,我会添加一个基于此。 – Steve314
你为什么不直接声明自己的API函数和标识符? –
@HarryJohnston - 我不知道如何定义标识符(类型应该是什么等),并猜测可能值得向Khronos和/或MinGW提交一些更改,我真的不知道什么是法律问题只是从Microsoft头文件(我目前没有)或MSDN上的某处(假设他们在某处)复制这些定义。但它仍然是一种选择。 – Steve314