您的位置:首页 > 编程语言 > C语言/C++

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

2016-01-24 01:17 537 查看
不太懂新的编译器

在编一个导出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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: