m0_74933830 2023-09-26 10:27 采纳率: 50%
浏览 20
已结题

微软SEAL库的安装和使用,VS2022环境配置问题

调用SEAL库中的例子的报错情况(csdn都翻烂了,怎么修改都无济于事)
**错误 LNK2001 无法解析的外部符号 main Project9 D:\VS\Project9\Project9\MSVCRT.lib(exe_main.obj) 1
错误 LNK1120 1 个无法解析的外部命令 Project9 D:\VS\Project9\x64\Release\Project9.exe 1 **

img

一、目前的vs2022配置情况
二、目前的SEAL库的安装情况
三、可以成功运行的例子

一、目前的vs2022配置情况

img

img

img

img

img

img

二、目前的SEAL库的安装情况

img

img

img

img

三、在cdsn上找到了两个可以成功运行的例子


#include "seal/seal.h"

#include <iostream>

#include <iomanip>



using namespace std;

using namespace seal;





/*
Helper function: Convert a value into a hexadecimal string, e.g., uint64_t(17) --> "11".
*/

inline std::string uint64_to_hex_string(std::uint64_t value)

{

    return seal::util::uint_to_hex_string(&value, std::size_t(1));

}



inline void print_line(int line_number)

{

    std::cout << "Line " << std::setw(3) << line_number << " --> ";

}



inline void print_parameters(const seal::SEALContext& context)

{

    auto& context_data = *context.key_context_data();



    /*
    Which scheme are we using?
    */

    std::string scheme_name;

    switch (context_data.parms().scheme())

    {

    case seal::scheme_type::bfv:

        scheme_name = "BFV";

        break;

    case seal::scheme_type::ckks:

        scheme_name = "CKKS";

        break;

    case seal::scheme_type::bgv:

        scheme_name = "BGV";

        break;

    default:

        throw std::invalid_argument("unsupported scheme");

    }

    std::cout << "/" << std::endl;

    std::cout << "| Encryption parameters :" << std::endl;

    std::cout << "|   scheme: " << scheme_name << std::endl;

    std::cout << "|   poly_modulus_degree: " << context_data.parms().poly_modulus_degree() << std::endl;



    /*
    Print the size of the true (product) coefficient modulus.
    */

    std::cout << "|   coeff_modulus size: ";

    std::cout << context_data.total_coeff_modulus_bit_count() << " (";

    auto coeff_modulus = context_data.parms().coeff_modulus();

    std::size_t coeff_modulus_size = coeff_modulus.size();

    for (std::size_t i = 0; i < coeff_modulus_size - 1; i++)

    {

        std::cout << coeff_modulus[i].bit_count() << " + ";

    }

    std::cout << coeff_modulus.back().bit_count();

    std::cout << ") bits" << std::endl;



    /*
    For the BFV scheme print the plain_modulus parameter.
    */

    if (context_data.parms().scheme() == seal::scheme_type::bfv)

    {

        std::cout << "|   plain_modulus: " << context_data.parms().plain_modulus().value() << std::endl;

    }



    std::cout << "\\" << std::endl;

}



void example_bfv()

{

    cout << "Example BFV Basic.";

    EncryptionParameters parms(scheme_type::bfv);//生成方案所需参数

    size_t poly_modulus_degree = 4096; //设置多项式的度数

    parms.set_poly_modulus_degree(poly_modulus_degree);

    parms.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));

    parms.set_plain_modulus(1024);

    cout << "Set encryption parameters and print" << endl;

    SEALContext context(parms);

    print_parameters(context);

    cout << "Parameter validation (success): " << context.parameter_error_message() << endl;



    cout << endl;

    cout << "~~~~~~ A naive way to calculate 4(x^2+1)(x+1)^2. ~~~~~~" << endl;



    /*
    生成密钥
    */

    KeyGenerator keygen(context);

    SecretKey secret_key = keygen.secret_key();

    PublicKey public_key;

    keygen.create_public_key(public_key);

    /*
    生成加密器,eval器,解密器
    */

    Encryptor encryptor(context, public_key);

    Evaluator evaluator(context);

    Decryptor decryptor(context, secret_key);



    /*
    加密明文6, 使用一个构造器将其构造成多项式表示的形式,系数以hex表示
    */

    print_line(__LINE__);

    uint64_t x = 6;

    Plaintext x_plain(uint64_to_hex_string(x));

    cout << "Express x = " + to_string(x) + " as a plaintext polynomial 0x" + x_plain.to_string() + "." << endl;



    /*
    使用加密器进行加密
    */

    print_line(__LINE__);

    Ciphertext x_encrypted;

    cout << "Encrypt x_plain to x_encrypted." << endl;

    encryptor.encrypt(x_plain, x_encrypted);

    /*
    BFV/BGV的密文一般都是两个或两个以上的多项式,多项式个数称为密文的size
    */

    cout << "    + size of freshly encrypted x: " << x_encrypted.size() << endl;

    /*
    格同态中有噪声的概念,会影响解密正确性,具体见文献吧
    */

    cout << "    + noise budget in freshly encrypted x: " << decryptor.invariant_noise_budget(x_encrypted) << " bits"

        << endl;

    /*
    解密密文
    */

    Plaintext x_decrypted;

    cout << "    + decryption of x_encrypted: ";

    decryptor.decrypt(x_encrypted, x_decrypted);

    cout << "0x" << x_decrypted.to_string() << " ...... Correct." << endl;



    /*
    计算加法
    */

    print_line(__LINE__);

    cout << "Compute x_sq_plus_one (x^2+1)." << endl;

    Ciphertext x_sq_plus_one;

    evaluator.square(x_encrypted, x_sq_plus_one);

    Plaintext plain_one("1");

    evaluator.add_plain_inplace(x_sq_plus_one, plain_one);

    cout << "    + size of x_sq_plus_one: " << x_sq_plus_one.size() << endl;

    cout << "    + noise budget in x_sq_plus_one: " << decryptor.invariant_noise_budget(x_sq_plus_one) << " bits"

        << endl;



}



int main() {

    example_bfv();

    return 0;

}

运行结果

img


另一个可以成功运行的代码

#include <iostream>
#include <vector>
#include "seal/seal.h"

using namespace std;
using namespace seal;

int main() {
    // 选定参数
    EncryptionParameters params(scheme_type::ckks);
    size_t poly_modulus_degree = 8192;
    params.set_poly_modulus_degree(poly_modulus_degree);
    params.set_coeff_modulus(CoeffModulus::BFVDefault(poly_modulus_degree));
    double scale = pow(2.0, 40);
    SEALContext context(params);

    // 生成 A 用户的密钥
    KeyGenerator keygen_A(context);
    PublicKey public_key_A;
    keygen_A.create_public_key(public_key_A);
    auto secret_key_A = keygen_A.secret_key();


    // 生成 B 用户的密钥
    KeyGenerator keygen_B(context);
    PublicKey public_key_B;
    keygen_B.create_public_key(public_key_B);
    auto secret_key_B = keygen_B.secret_key();


    // 实例化加密器、解密器和计算器
    Encryptor encryptor_A(context, public_key_B);//这个加密器用于加密对用户B可解密的密文
    Encryptor encryptor_A1(context, public_key_A);//这个加密器用于加密用户A的密文
    Evaluator evaluator_A(context);
    Decryptor decryptor_A(context, secret_key_A);//这个解密器用于解密用户A加密后的密文
    Encryptor encryptor_B(context, public_key_B);
    Decryptor decryptor_B(context, secret_key_B);
    Evaluator evaluator_B(context);

    // 生成 A 用户的数据并加密
    vector<double> vec_A{ 1.0 };
    CKKSEncoder encoder_A(context);
    size_t slot_count_A = encoder_A.slot_count();
    Plaintext plain_A;
    encoder_A.encode(vec_A, scale, plain_A);
    Ciphertext encrypted_A;
    encryptor_A.encrypt(plain_A, encrypted_A);
    //加密用户A的数据
    Ciphertext encrypted_A1;
    encryptor_A1.encrypt(plain_A, encrypted_A1);

    // 生成 B 用户的数据并加密
    vector<double> vec_B{ 9.0 };
    CKKSEncoder encoder_B(context);
    size_t slot_count_B = encoder_B.slot_count();
    Plaintext plain_B;
    encoder_B.encode(vec_B, scale, plain_B);
    Ciphertext encrypted_B;
    encryptor_B.encrypt(plain_B, encrypted_B);

    // 对两个加密数据进行加法
    Ciphertext encrypted_sum;
    evaluator_B.add(encrypted_A, encrypted_B, encrypted_sum);

    // 解密加法结果并解码
    Plaintext plain_sum;
    decryptor_B.decrypt(encrypted_sum, plain_sum);
    vector<double> vec_sum;
    encoder_B.decode(plain_sum, vec_sum);
    cout << "Decrypted result: " << vec_sum[0] << endl;
    //解密用户A的数据
    Plaintext plain_A1;
    decryptor_A.decrypt(encrypted_A1, plain_A1);
    vector<double> vec_A1;
    encoder_A.decode(plain_A1, vec_A1);
    cout << "Decrypted result: " << vec_A1[0] << endl;

    return 0;
}



运行结果

img


除了这两个,其他的例子都不能成功运行,最重要的是,SEAL库中的例子都不能成功运行,报错结果放在了文章开始的位置。

听取评论区的建议后,将原来的 void bfv_performance_test() 改为int main(){return 0;}后, 成功了。那为啥SEAL库的例子要给void而不是直接给int main呢?

img

  • 写回答

8条回答 默认 最新

  • 专家-赤兔[在线] 2023-09-26 11:04
    关注

    引自免费微信小程序-皆我百晓生,希望对题主有所帮助,如有帮助,还望采纳。


    对于使用微软SEAL库安装和调用的问题,你遇到的错误是链接错误(LNK2001LNK1120),这通常是由于你的项目缺少主函数main造成的。为了解决这个问题,你需要在你的项目中添加一个包含主函数main的源文件。你可以创建一个新的源文件,并将以下代码添加到该文件中:

    #include <iostream>
    #include <seal/seal.h>
    
    using namespace std;
    using namespace seal;
    
    int main()    
    {
        // 在这里编写你需要使用SEAL库的代码    
        return 0;
    }
    

    然后将该文件添加到你的项目中,并进行构建和运行。此外,还需要确保你的项目已正确配置SEAL库和VS2022环境。你可以按照以下步骤进行操作:

    1. 确保你已经正确下载和安装了SEAL库。可以从SEAL库的官方网站(https://github.com/microsoft/SEAL)下载最新版本的库。
    2. 在VS2022中创建一个新的空项目。
    3. 将SEAL库的头文件和库文件添加到你的项目中。在VS2022中,右键点击你的项目,选择"属性",然后依次选择"C/C++"和"常规"。在"附加包含目录"选项中添加SEAL库的include目录。接下来,选择"链接器"和"常规",在"附加库目录"选项中添加SEAL库的库文件目录。最后,在"链接器"和"输入"选项中,添加SEAL库的.lib文件名称。
    4. 确保你的项目的属性设置为x64平台,以与SEAL库匹配。右键点击的项目,选择"属性",然后选择"配置属性",将"平台"设置为"x64"。
    5. 重新构建你的项目,并运行。

    希望以上步骤可以帮助你解决问题。如果问题仍然存在,请提供更多详细的错误信息和项目配置信息,以便我们更好地帮助你解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 「已注销」 2023-09-26 10:44
    关注

    检查SEAL库的安装:请确保您已正确安装并配置了SEAL库。根据您提供的信息,可能存在某些依赖项未正确安装或路径配置不正确的问题。

    评论
  • 小明说Java 2023-09-26 12:53
    关注

    引用文心一言并结合自己思考回答:
    看起来你在使用Visual Studio 2022来编译和运行SEAL库中的例子,但是遇到了一些链接错误。从给出的错误信息看,似乎是在链接阶段找不到“main”函数。这通常是由于项目设置或代码中的问题导致的。

    首先,请确保你的项目设置是正确的。你需要将SEAL库的头文件路径和库文件路径正确配置在你的项目中。这通常需要在你的项目属性中设置“C/C++”->“常规”->“附加包含目录”和“链接器”->“常规”->“附加库目录”。

    其次,确保你的代码中包含了正确的头文件,并且链接了正确的库文件。在编译SEAL库的例子时,你通常需要包含SEAL库的头文件,并且链接SEAL库的库文件。

    最后,如果上述步骤都没有问题,那么可能是SEAL库的例子中没有定义main函数。在C++程序中,main函数是程序的入口点,如果没有定义main函数,那么在链接阶段就会找不到入口点,从而导致链接错误。你可以尝试在你的代码中添加一个main函数,然后调用SEAL库的例子中的函数。

    这是一个基本的main函数示例:

    
    #include <iostream>  
      
    int main() {  
        std::cout << "Hello, World!" << std::endl;  
        return 0;  
    }
    
    评论
  • cyjbj 2023-09-26 13:17
    关注

    高级,顶一下

    评论
  • 急速光粒 2023-09-26 14:56
    关注

    没看到project9的源码,不好判断。貌似没有入口main函数。

    评论
  • threenewbee 2023-09-26 15:50
    关注

    无法解析外部符号main?你定义了main函数了没有。

    评论
  • 以免我忘记 2023-09-26 16:08
    关注

    应该是静态引用没有加上,比如你用了"123.lib"里的函数,就要加上引用 #pragma comment(lib,"123.lib")

    评论
  • 玥轩_521 2023-09-26 20:10
    关注

    援引讯飞星火:
    这个问题可能是由于在项目文件中没有正确配置SEAL库的包含路径和库文件路径导致的。请按照以下步骤进行操作:

    1. 打开项目文件(Project9),右键点击项目名称,选择“属性”。
    2. 在弹出的属性窗口中,依次选择“VC++目录”->“包含目录”,然后添加SEAL库的include目录。例如,如果你的SEAL库安装在C:\SEAL目录下,那么添加C:\SEAL\include
    3. 接下来,选择“链接器”->“输入”,在“附加依赖项”中添加SEAL库的lib文件。例如,将seal.lib添加到列表中。
    4. 点击“应用”按钮,保存更改。
    5. 重新编译项目,看看问题是否解决。

    如果问题仍然存在,可以尝试将SEAL库的include目录和lib文件路径添加到系统环境变量中。这样,编译器和链接器可以在任何位置找到这些文件。具体操作如下:

    1. 右键点击“计算机”图标,选择“属性”。
    2. 在弹出的窗口中,点击“高级系统设置”。
    3. 在“系统属性”窗口中,点击“环境变量”按钮。
    4. 在“环境变量”窗口中,找到“Path”变量,双击编辑。
    5. 在“编辑环境变量”窗口中,点击“新建”,然后添加SEAL库的include目录和lib文件路径。例如,添加C:\SEAL\includeC:\SEAL\lib
    6. 点击“确定”按钮,保存更改。
    7. 重新打开Visual Studio 2022,重新编译项目。
    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 系统已结题 10月4日
  • 已采纳回答 9月26日
  • 修改了问题 9月26日
  • 创建了问题 9月26日

悬赏问题

  • ¥30 哈夫曼编码译码器打印树形项目
  • ¥20 求完整顺利登陆QQ邮箱的python代码
  • ¥15 怎么下载MySQL,怎么卸干净原来的MySQL
  • ¥15 网络打印机Ip地址自动获取出现问题
  • ¥15 求局部放电案例库,用于预测局部放电类型
  • ¥100 QT Open62541
  • ¥15 stata合并季度数据和日度数据
  • ¥15 谁能提供rabbitmq,erlang,socat压缩包,记住版本要对应
  • ¥15 Vue3 中使用 `vue-router` 只能跳转到主页面?
  • ¥15 用QT,进行QGIS二次开发,如何在添加栅格图层时,将黑白的矢量图渲染成彩色