不太懂新的编译器
在编一个导出Free函数的DLL时遇到了莫名其妙的错误(Win7 x64,RAM 16G)
文件main.cpp代码:
#ifdef UNICODE
#undef UNICODE
#endif
#include <Windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
int Free(int arg1, int arg2, int arg3)
{
return 0;
}
文件Source.def代码(导出不是Windows API的__stdcall而是C/C++语言默认的__cdecl方式):
LIBRARY MyFuckingDLL
EXPORTS
Free
编译结果:
1>------ 已启动生成: 项目: Win32Project1, 配置: Debug Win32 ------
1> main.cpp
1>Source.def : warning LNK4022: 找不到符号“Free”的唯一匹配项
1>Source.def : warning LNK4002: "int __cdecl Free(int,int,int)" (?Free@@YAHHHH@Z) 在 Debug\main.obj 中定义
1>Source.def : warning LNK4002: "void __cdecl Concurrency::Free(void *)" (?Free@Concurrency@@YAXPAX@Z) 在 D:\Program Files\Microsoft Visual Studio 11.0\VC\lib\MSVCRTD.lib 中定义
1>Source.def : error LNK2001: 无法解析的外部符号 Free
1>E:\Codes\2016\Win32Project1\Debug\Win32Project1.lib : fatal error LNK1120: 1 个无法解析的外部命令
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
我看Concurrency是命名空间,于是想,换C语言得不得,想取消C++定义,代码:
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef __cplusplus
#undef __cplusplus
#endif
#include <Windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
int Free(int arg1, int arg2, int arg3)
{
return 0;
}
结果:
1>------ 已启动生成: 项目: Win32Project1, 配置: Debug Win32 ------
1> main.cpp
1>e:\codes\2016\win32project1\win32project1\main.cpp(5): warning C4117: 保留“__cplusplus”宏名,忽略“#undef”
1>Source.def : warning LNK4022: 找不到符号“Free”的唯一匹配项
1>Source.def : warning LNK4002: "int __cdecl Free(int,int,int)" (?Free@@YAHHHH@Z) 在 Debug\main.obj 中定义
1>Source.def : warning LNK4002: "void __cdecl Concurrency::Free(void *)" (?Free@Concurrency@@YAXPAX@Z) 在 D:\Program Files\Microsoft Visual Studio 11.0\VC\lib\MSVCRTD.lib 中定义
1>Source.def : error LNK2001: 无法解析的外部符号 Free
1>E:\Codes\2016\Win32Project1\Debug\Win32Project1.lib : fatal error LNK1120: 1 个无法解析的外部命令
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
我x他x的xx的xx……
于是改文件名为*.c,重新编译:
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef __cplusplus
#undef __cplusplus
#endif
#include <Windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
int Free(int arg1, int arg2, int arg3)
{
union {
int i1;
char *name1;
union {
int i2;
char *action;
union {
int i3;
char *name2;
union {
int times;
char *count;
};
};
};
};
name1 = "I";
action = "fuck";
name2 = "microsoft";
count = "100 times!";
return 0;
}
结果:
1>------ 已启动生成: 项目: Win32Project1, 配置: Debug Win32 ------
1> main.c
1>e:\codes\2016\win32project1\win32project1\main.c(32): warning C4094: 无标记的“union”未声明符号
1>e:\codes\2016\win32project1\win32project1\main.c(34): error C2065: “name1”: 未声明的标识符
1>e:\codes\2016\win32project1\win32project1\main.c(34): warning C4047: “=”:“int”与“char [2]”的间接级别不同
1>e:\codes\2016\win32project1\win32project1\main.c(35): error C2065: “action”: 未声明的标识符
1>e:\codes\2016\win32project1\win32project1\main.c(35): warning C4047: “=”:“int”与“char [5]”的间接级别不同
1>e:\codes\2016\win32project1\win32project1\main.c(36): error C2065: “name2”: 未声明的标识符
1>e:\codes\2016\win32project1\win32project1\main.c(36): warning C4047: “=”:“int”与“char [10]”的间接级别不同
1>e:\codes\2016\win32project1\win32project1\main.c(37): error C2065: “count”: 未声明的标识符
1>e:\codes\2016\win32project1\win32project1\main.c(37): warning C4047: “=”:“int”与“char [11]”的间接级别不同
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
最终只能是:
#ifdef UNICODE
#undef UNICODE
#endif
#ifdef __cplusplus
#undef __cplusplus
#endif
#include <Windows.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}
int Free(int arg1, int arg2, int arg3)
{
union {
int i1;
char *name1;
union {
int i2;
char *action;
union {
int i3;
char *name2;
union {
int times;
char *count;
} For;
} Microsoft;
} Fuck;
} I;
I.Fuck.Microsoft.For.times = 100;
return 0;
}
结果:
1>------ 已启动生成: 项目: Win32Project1, 配置: Debug Win32 ------
1> main.c
1> Win32Project1.vcxproj -> E:\Codes\2016\Win32Project1\Debug\Win32Project1.dll
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
姥姥……
2016-01-24 01:16:12