【问题标题】:I would like to convert this Borland C++ code into workable Visual Studio C++ Code, Some Issues [closed]我想将此 Borland C++ 代码转换为可用的 Visual Studio C++ 代码,一些问题 [关闭]
【发布时间】:2019-04-09 00:24:49
【问题描述】:

我有一些旧的 Borland C++ 源代码需要转换成 Visual Studio C++ 代码。我得到了一些工作,但是遇到了一些“const chars”和“unsigned chars”的障碍。特别是 IP 寻址和端口寻址(第 15 - 28 行,错误指向第 44 行)

    // test1.cpp 5/23/97

    // example Win32 C++ program to read registers from PLC via gateway

    // compile with BC45 or BC50
    // default settings for Win32 console app
    // empty DEF file

    #include <winsock2.h>
    #include <stdio.h>
    #include <conio.h>



    int main(int argc, char** argv)
    {
        if (argc < 5)
        {
            printf("usage: test1 ip_adrs unit reg_no num_regs\n"
                "eg test1 198.202.138.72 5 0 10\n");
            return 1;
        }
        char* ip_adrs = argv[1];
        unsigned short unit = atoi(argv[2]);
        unsigned short reg_no = atoi(argv[3]);
        unsigned short num_regs = atoi(argv[4]);
        printf("ip_adrs = %s unit = %d reg_no = %d num_regs = %d\n",
            ip_adrs, unit, reg_no, num_regs);

        // initialize WinSock
        static WSADATA wd;
        if (WSAStartup(0x0101, &wd))
        {
            printf("cannot initialize WinSock\n");
            return 1;
        }

        // set up socket
        SOCKET s;
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(502); // ASA standard port
        server.sin_addr.s_addr = inet_addr(ip_adrs);
        int i;
        i = connect(s, (sockaddr*)& server, sizeof(sockaddr_in));
        if (i < 0)
        {
            printf("connect - error %d\n", WSAGetLastError());
            closesocket(s);
            WSACleanup();
            return 1;
        }
        fd_set fds;
        FD_ZERO(&fds);
        timeval tv;
        tv.tv_sec = 5;
        tv.tv_usec = 0;

        // wait for permission to send
        FD_SET(s, &fds);
        i = select(32, NULL, &fds, NULL, &tv); // write
        if (i <= 0)
        {
            printf("select - error %d\n", WSAGetLastError());
            closesocket(s);
            WSACleanup();
            return 1;
        }

        // build request of form 0 0 0 0 0 6 ui 3 rr rr nn nn
        unsigned char obuf[261];
        unsigned char ibuf[261];
        for (i = 0; i < 5; i++) obuf[i] = 0;
        obuf[5] = 6;
        obuf[6] = unit;
        obuf[7] = 3;
        obuf[8] = reg_no >> 8;
        obuf[9] = reg_no & 0xff;
        obuf[10] = num_regs >> 8;
        obuf[11] = num_regs & 0xff;

        // send request
        i = send(s, reinterpret_cast<char*>(obuf), 12, 0);
        if (i < 12)
        {
            printf("failed to send all 12 chars\n");
        }

        // wait for response
        FD_SET(s, &fds);
        i = select(32, &fds, NULL, NULL, &tv); //read
        if (i <= 0)
        {
            printf("no TCP response received\n");
            closesocket(s);
            WSACleanup();
            return 1;
        }

        // read response
        i = recv(s, reinterpret_cast<char*>(ibuf), 261, 0);
        if (i < 9)
        {
            if (i == 0)
            {
                printf("unexpected close of connection at remote end\n");
            }
            else
            {
                printf("response was too short - %d chars\n", i);
            }
        }
        else if (ibuf[7] & 0x80)
        {
            printf("MODBUS exception response - type %d\n", ibuf[8]);
        }
        else if (i != (9 + 2 * num_regs))
        {
            printf("incorrect response size is %d expected %d\n", i, (9 + 2 * num_regs));
        }
        else
        {
            for (i = 0; i < num_regs; i++)
            {
                unsigned short w = (ibuf[9 + i + i] << 8) + ibuf[10 + i + i];
                printf("word %d = %d\n", i, w);
            }
        }

        // close down
        closesocket(s);
        WSACleanup();
        return 0;
    }

这是连接模拟器的代码,这里的IP和socket值不正确。然而,这不应该是问题,真正的障碍是“字符”的转换。感谢您提供任何反馈。

IP 的正确目的地是 DESKTOP-E503UCE 或 192.168.0.11,服务器设置下列出的端口是 502。请注意,上面的 IP 是本地 IP(我的电脑)

此外,当前发生的唯一错误是代码 C4996 - 'inet_addr':请改用 inet_pton() 或 Inet_Pton() 或定义 _WINSTOCK_DEPREACTED_NO_WARNINGS 以禁用第 44 行的已弃用 API 警告。

【问题讨论】:

  • 究竟输出了什么错误?
  • 嗨科伦! Jorge 下面的回答解决了我遇到这些错误的问题。但是,我现在遇到了一些与 IP 连接相关的新问题。似乎当我修复一件事时,另一件事会出错。如果这超出了本网站的范围,我深表歉意,我正在寻找有关如何转换/连接到此模拟器的一些见解。
  • TBH,这是socket代码,socket代码头是C语言的。你应该看看一些socket编程教程,比如geeksforgeeks.org/socket-programming-ccbogotobogo.com/cplusplus/sockets_server_client.php(高谷歌链接)
  • "此外,当前发生的唯一错误是代码 C4996" - 正如警告所说,inet_addr() 已弃用,您应该使用 inet_pton()Inet_Pton()相反,或者您可以在#include &lt;winsock2.h&gt; 上方添加#define _WINSTOCK_DEPREACTED_NO_WARNINGS 语句以禁用警告。

标签: c++ visual-c++ borland-c++


【解决方案1】:

有一个非常简单的修复方法 - 我们可以在第 75 行和第 93 行添加一个 reinterpret_cast

第 70 行:

i = send(s, reinterpret_cast<char*>(obuf), 12, 0); // Line 75

第 86 行:

i = recv(s, reinterpret_cast<char*>(ibuf), 261, 0); // Line 93

为什么我们必须这样做?

Borland 让您在规则上玩得又快又松,它会自动为您完成这些演员阵容。

这些转换是安全的,不会调用未定义的行为,但最好明确说明它们。

【讨论】:

  • 就类型而言,char name[]char* name 相同,真正需要的是声明中的unsigned 关键字,因为unsigned char* 是与char*不同
  • 它们可以安全地相互转换,并且在某些情况下您希望使用unsigned char 而不是char。例如,对于char,溢出是UB,但对于unsigned char,它是明确定义的。在这种情况下,使用reinterpret_cast 是最安全的解决方案。
  • 据我所知,reinterpret_cast 是最危险的演员阵容。但实际上,他也可以让 printfs 支持 std::cout(鉴于 Borland C++ 从未使用过 &lt;iostream&gt;
  • charunsigned char 保证大小相同,并且保证在它们之间投射是安全的
  • 它变成负数是 fine 因为二进制表示是相同的。在大多数使用unsigned char 代替char 的情况下,他们使用unsigned char,因为他们需要它是正数(因为它被用作索引或其他东西,例如哈希函数或映射或a trie),而环绕的值在转换为 char 时无关紧要。
猜你喜欢
  • 1970-01-01
  • 2014-09-16
  • 1970-01-01
  • 2022-01-16
  • 2013-12-13
  • 2023-03-09
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多