【问题标题】:adding ipv6 support to Rainmeter为 Rainmeter 添加 ipv6 支持
【发布时间】: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 &lt;iphlpapi.h&gt;。
  • 我查看了文档,但我似乎没有将 2 和 2 放在一起。
  • @WhitequillRiclo 函数GetTcp6Table 在iphlpapi.h 中声明,而这又需要winsock2.h。如果您打开iphlpapi.h 文件,您会在GetTcp6Table 的声明之前找到注释“以下定义需要Winsock2”。最初,你#include'd 那些标题之前 windows.h,现在你移动它们之后 windows.h,但仍然未定义WIN32_LEAN_AND_MEAN 导致我的答案末尾引用中解释的冲突。

标签: c++ winapi visual-c++


【解决方案1】:

Win32 标头 &lt;winsock2.h&gt; 和 &lt;windows.h&gt; 之间存在已知冲突,请参见例如 1、2。

Microsoft documentation 建议使用两个#include 序列之一。

  • 没有&lt;windows.h&gt;:
#include <winsock2.h>
#include <ws2tcpip.h>
  • 与&lt;windows.h&gt;:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>

由于GetTcp6Table 需要&lt;iphlpapi.h&gt; 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-&gt;table[measure-&gt;data].dwLocalPort;的时候没有给出单播地址,否则问题就彻底解决了。
  • IP 不在dwLocalPort 中,详情请参阅MIB_TCP6ROW structure。
猜你喜欢
  • 2018-06-01
  • 2021-10-03
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多