我正在使用objcopy将文本文件转换为目标文件,以便使用MinGW和MinGW-64链接我的DLL。使用MinGW,一切正常,但是使用MinGW-64,我得到“未定义引用`binary_src_glsl_RGBtoHSV_glsl_end'”形式的错误。原始文件名为RGBtoHSV.glsl,位于文件夹binary \ src \ glsl中。在objcopy的输出中,变量名是_binary_src_glsl_RGBtoHSV_glsl_end。我访问该文件变量的代码如下:
extern "C" const char binary_src_glsl_RGBtoHSV_glsl_start;
extern "C" const char binary_src_glsl_RGBtoHSV_glsl_end;
const std::string RGBtoHSV = std::string(&binary_src_glsl_RGBtoHSV_glsl_start, &binary_src_glsl_RGBtoHSV_glsl_end-&binary_src_glsl_RGBtoHSV_glsl_start);
如果我更改变量名称,使它们前面有一个下划线,例如:
extern "C" const char _binary_src_glsl_RGBtoHSV_glsl_start;
然后在MinGW-64中找到该符号,但在MinGW(32位)中找不到。我确实尝试使用--remove-remove-leading-char选项进行objcopy但是没有效果。据我所知,我的选择是在为MinGW 32位构建时使用“--prefix-symbol _”为objcopy生成的变量名添加下划线,在这种情况下,上面的变量名将在32中工作和64位。
这个问题有另一个解决方案吗?理想情况下,我喜欢
的内容extern "C" fix_underscore_problem const char binary_src_glsl_RGBtoHSV_glsl_start;
其中fix_underscore_problem是修复前导下划线问题的魔术命令。
更新(2012-07-01):使用Adding leading underscores to assembly symbols with GCC on Win32?中给出的建议我按头文件更改使用
extern "C" const char binary_src_glsl_RGBtoHSV_glsl_start asm("_binary_src_glsl_RGBtoHSV_glsl_start");
这似乎解决了这个问题,但现在我想知道这是多么便携。在MSVC或C ++标准方法中是否有可用的等效语法?
答案 0 :(得分:1)
好吧,我已经解决了这个问题,通过定义一个宏来创建一个带有前导下划线的变量,如果需要的话。然后它创建一个返回指向变量的指针的函数。函数名将始终是传递给宏的名称,因此我的其余代码可以只使用该函数名。宏是:
#define GPUFW_STR(x) #x
#if defined(__GNUC__) | defined(__MINGW32__) | defined(__MINGW64__)
//GCC and MinGW allow one to use the asm keyword to give a variable a
//specific label, overriding the label used at compile time.
#define GPUFW_BINARY_BLOB_EXTERN(T,x) extern "C" const T x asm(GPUFW_STR(_ ## x)); static const T* at_ ## x = &x;
#else
#if defined(_MSC_VER)
#if defined(_WIN32)
//Visual C++ does not seem to have a method to specify a different
//label for a variable at link time, but in 32-bit Windows
//extern "C" variables have a leading underscore anyway.
#define GPUFW_BINARY_BLOB_EXTERN(T,x) extern "C" const T x; static const T* at_ ## x = &x;
#else
//64-bit Visual C++ does not prepend an underscore to extern "C"
//variable names, causing many problems here. Hence define the
//external variable as _x.
#define GPUFW_BINARY_BLOB_EXTERN(T,x) extern "C" const T _##x; static const T* at_ ## x = &_ ## x;
#endif
#else
//Unknown compiler.
#warning Your compiler was not recognised by GPUFW. Binary blob inclusion may produce linker errors.
#if defined(_WIN64)
//On 64-bit Windows most compilers seem to stick to the Visual C++
//naming conventions.
#define GPUFW_BINARY_BLOB_EXTERN(T,x) extern "C" const T _##x; static const T* at_ ## x = &_ ## x;
#else
//If all else fails, hope that the compiler uses a leading underscore.
#define GPUFW_BINARY_BLOB_EXTERN(T,x) extern "C" const T x; static const T* at_ ## x = &x;
#endif
#endif
#endif
我很感激任何有关改进此解决方案的建议。特别是我可以添加到处理除GCC和MSVC以外的编译器的分支的任何内容,因为我没有经验。
作为旁注,我也尝试使用ld来制作包含我的文本的目标文件,但是遇到了同样的问题,无论我使用什么选项,我都无法删除前导下划线。