VS2012中C语言不支持匿名联合,导出函数不界定范围

不太懂新的编译器

在编一个导出Free函数的DLL时遇到了莫名其妙的错误(Win7 x64,RAM 16G)

VS2012中C语言不支持匿名联合,导出函数不界定范围_第1张图片

VS2012中C语言不支持匿名联合,导出函数不界定范围_第2张图片


文件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

你可能感兴趣的:(VS2012中C语言不支持匿名联合,导出函数不界定范围)