为 Rainmeter 添加 ipv6 支持
Posted
技术标签:
【中文标题】为 Rainmeter 添加 ipv6 支持【英文标题】:adding ipv6 support to Rainmeter 【发布时间】:2020-06-23 03:54:50 【问题描述】:我正在尝试从 Rainmeter API 编辑 PluginSysInfo 以包含 IPv6 支持。我已经修改了 SysInfo.cpp 中的代码,据我所知包含的链接具有我对 SysInfo.cpp 所做的编辑。
当我在 Visual Studio 中构建它时,“标识符 GetTcp6Table 未定义”和“标识符 PMIB_IP6TABLE 未定义”即使它们位于包含文件 #include
https://pastebin.com/N30HYRVe
#include <algorithm>
#include <windows.h>
#include <WinSock2.h>
...
MEASURE_IP6_ADDRESS
...
else if (_wcsicmp(L"IP6_ADDRESS", type) == 0)
defaultData = 0;
measure->type = MEASURE_IP6_ADDRESS;
...
case MEASURE_IP6_ADDRESS:
if (NO_ERROR == GetTcp6Table((PMIB_IP6TABLE)tmpBuffer, &tmpBufferLen, FALSE))
PMIB_IP6TABLE TcpTable = (PMIB_IP6TABLE)tmpBuffer;
if (measure->useBestInterface)
for (UINT i = 0; i < TcpTable->dwNumEntries; ++i)
if (TcpTable->table[i].dwIndex == measure->data)
DWORD ip = TcpTable->table[i].dwAddr;
wsprintf(sBuffer, L"%x:%x:%x:%x"/*:%x:%x:%x:%x"*/, ip % 65535, (ip >> 8) % 65535, (ip >> 16) % 65535, (ip >> 24) % 65535);
return sBuffer;
【问题讨论】:
documentation 表示您需要#include <iphlpapi.h>
。
我查看了文档,但我似乎没有将 2 和 2 放在一起。
@WhitequillRiclo 函数GetTcp6Table
在iphlpapi.h
中声明,而这又需要winsock2.h
。如果您打开iphlpapi.h
文件,您会在GetTcp6Table
的声明之前找到注释“以下定义需要Winsock2”。最初,你#include
'd 那些标题之前 windows.h
,现在你移动它们之后 windows.h
,但仍然未定义WIN32_LEAN_AND_MEAN
导致我的答案末尾引用中解释的冲突。
【参考方案1】:
Win32 标头 <winsock2.h>
和 <windows.h>
之间存在已知冲突,请参见例如 1、2。
Microsoft documentation 建议使用两个#include
序列之一。
<windows.h>
:
#include <winsock2.h>
#include <ws2tcpip.h>
与<windows.h>
:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
由于GetTcp6Table
需要<iphlpapi.h>
OP 的情况应该使用后一种。
引用同一文档:
如果应用程序使用 IP Helper API,则需要 Iphlpapi.h 头文件。当需要 Iphlpapi.h 头文件时, Winsock2.h 头文件的#include 行应放在 Iphlpapi.h 头文件的#include 行之前。
Winsock2.h 头文件内部包含来自 Windows.h 头文件的核心元素,因此 Winsock 应用程序中的 Windows.h 头文件通常没有#include 行。 如果 Windows.h 头文件需要 #include 行,则应在其前面加上 #define WIN32_LEAN_AND_MEAN 宏。 由于历史原因,Windows.h 头文件默认包括 Windows Sockets 1.1 的 Winsock.h 头文件。 Winsock.h 头文件中的声明将与 Windows Sockets 2.0 所需的 Winsock2.h 头文件中的声明冲突。 WIN32_LEAN_AND_MEAN 宏防止 Winsock.h 包含在 Windows.h 标头中。
[ EDIT ] 跟进评论,下面是正确构建的完整 sn-p。
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winwock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdlib.h> // _countof
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
int main()
BYTE tmpBuffer[7168];
ULONG tmpBufferLen = _countof(tmpBuffer);
return NO_ERROR == GetTcp6Table((PMIB_TCP6TABLE)tmpBuffer, &tmpBufferLen, FALSE);
【讨论】:
我已经更新了 pastebin 上的链接代码。我似乎仍然有同样的问题。我是 python3 开发人员。我不习惯 C++。 @WhitequillRiclo 我将完整的代码 sn-p 编辑为答案。注意GetTcp6Table
的第一个参数是PMIB_TCP6TABLE
,而不是PMIB_IP6TABLE
。
有点离题但是; PMIB_TCP6TABLE
读什么?因为我用DWORD ip = TcpTable->table[measure->data].dwLocalPort;
的时候没有给出单播地址,否则问题就彻底解决了。
IP 不在dwLocalPort
中,详情请参阅MIB_TCP6ROW structure。以上是关于为 Rainmeter 添加 ipv6 支持的主要内容,如果未能解决你的问题,请参考以下文章
centOS添加ipv6支持(仅限已分配ipv6地址和网关)