【问题标题】:Change a constant variable without rebuilding C++更改常量变量而不重建 C++
【发布时间】:2018-11-01 22:07:11
【问题描述】:

我使用 Visual Studio 2015 开发了一个 c++ 项目。我的项目的输出是一个单一的可执行文件,每个客户端都必须有一个唯一的 ID,并且该 ID 必须可以在代码中访问。一种简单的方法是在代码中定义一个常量变量,并为每个客户端更改其值并多次构建它,但我有一个 Linux 服务器,我不确定是否可以构建它,因为我使用了许多 Winapi 库.我在想也许还有另一种方法可以更改或向输出添加一些常量值,例如操作可执行文件。 例如:

#include <string>
#include <iostream>
#include <Windows.h>


const std::string ID = "some unique ID";

int main() {
    std::cout << "Your ID: " << ID << std::endl;
    getchar();
    return(0);
}

【问题讨论】:

  • 把id放到配置文件里?将其作为参数传递给程序?
  • 好吧,我假设他会提供一个自定义可执行文件的下载链接,该文件具有分配给该特定下载器的 ID,因此热修补标准可执行文件可能是重新编译整个东西的替代方法(顺便说一下 ID也可以在补丁时加密并在运行时解密)
  • @MasoudR。 -- 首先,这是一个 Windows 程序吗?如果是这样,您可以创建一个string resource 并直接在可执行文件中进行更改。我知道这违反了您没有其他程序的规则,而是just to illustrate that it can be done。您只需要弄清楚执行此操作的机制即可。
  • 也许这个链接可以帮助everydaywithlinux.blogspot.com.ar/2012/11/…

标签: c++ visual-studio compilation


【解决方案1】:

似乎只有两种方法。一种是在 Linux 环境中构建项目,这是一种更好的方法,但必须使用一些工具,如Mono XBuildlink here。 另一个可能更简单的选项是打开二进制文件并操作特定的字符串。正如@aloMalbarez 评论这里是一个基于this 的简单脚本。 假设这个例子:(我使用 50 ms 作为我的 ID 的固定长度)

#include <string>
#include <iostream>
#include <Windows.h>

#define ID "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"


using namespace std;

int main() {
    cout << "Your ID: " << ID << "\nlen:" << strlen(ID) <<  endl;
    getchar();
    return(0);
}

生成可执行文件后,使用以下脚本创建输出。 我不是 Linux 人,所以你可以帮助我改进这一点。 ./build.sh input.exe output.exe "myfixedID"

#!/bin/bash
# build.sh input_file output_file <ID>


input_file=$1
output_file=$2
ID=$3


if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
  echo "wrong parameters"
  echo "build.sh input_file output_file <ID>"
  exit 1
fi

# use fixed string (ID) in the source file
# this creates 50 of "m"s
search_value=$(printf 'm%.0s' {1..50})

extension=".back"
temp_file="$input_file$extension"
tmpstring_file="./tmp"
null_termin='\0'


echo "copying the original file..."
yes | cp -rf $input_file $temp_file

address=$(strings -t d $temp_file | grep $search_value | grep -o '[0-9]*')

echo "Address:"
echo $address
if ! [[ $address =~ ^[0-9]+$ ]]; then
  echo "cannot find valid ID in executable"
  echo "removing temps"
  rm $temp_file
  exit 1
fi


# make the tempstring file
printf "$ID$null_termin" > $tmpstring_file

dd if=$tmpstring_file of=$temp_file obs=1 seek=$address conv=notrunc

echo "make new file"
yes | cp -rf $temp_file $output_file

echo "removing temps"

rm $temp_file $tmpstring_file

echo "Done!"

【讨论】:

    【解决方案2】:

    在程序的初始化函数中。生成基于 SHA-1 的唯一 id 当前时间的哈希,IP 地址,用户名(更多相同)。之后您可以在该程序中做任何您想做的事情(即保存在数据库中)。这行得通吗?

    【讨论】:

    • 谢谢,但是 ID 是恒定的,必须为服务器所知,并且为每个可能的客户端构建 1000 次并不是一个好主意。
    • 客户端和服务器能否根据相同的信息生成ID。例如,基于用户名、电子邮件地址、用户 ID(使用 SHA-1 之类的哈希函数)?那么,服务器可以在不显式传递信息的情况下知道客户端?
    • @你是对的,这样可以实现,但是服务器不知道什么是客户端,只需要制作具有唯一 ID 的可执行文件即可。
    【解决方案3】:

    常量不是变量,它们是相反的类型。常量是一个元素,它被分配了一个不变的特定值,因此单词常量,不变。
    另一方面,变量是作为可变值存储在内存中的元素,当您的程序运行时,变量可以改变它的当前值。

    在 Visual Studio 中,您可以创建一个将设置值传递给程序的配置文件,这些值是可变的,并且可以通过编程和手动方式进行更改。但是,正如您所说,您不希望使用单独的文件来查找信息。

    如果您想通过用户的唯一 ID 跟踪用户,那么您必须在某个地方有一个可以记录新用户并颁发唯一 ID 的数据库,或者,您可以根据帐户所在的日期和时间创建一个唯一 ID已创建,如果您为每个文件创建一个唯一的可执行文件,则日期/时间信息包含在文件创建信息中,因此您只需使用它,因为每个文件都是在唯一的日期/时间创建的,这将始终指示ID。您可以为每个文件保留相同的名称,或将日期/时间合并到文件名中,例如 myPro20180522183231.exe,即 2018 年 月 05 日 22 小时 18 分 32 秒 31,这可以通过日期/时间信息来确认文件创建数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-01
      • 2018-01-26
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多