Search code examples
rustrust-cargo

the Rust file is not compiled into the dll


I'm new to Rust, so I don't know how to fix the error. I understood that the libraries were not imported, but in the file cargo.toml all the libraries are imported. sus_fns.rs:

use std::fs;
use rand::Rng;
use regex::Regex;

pub fn generate_memes_text(chat_id: &str) -> String {
    let filename = format!("../all_databases/stytsko_folder_id_{}_v/stytsko_db_mod=one-line_id_{}_v.txt", chat_id, chat_id);
    let _contents = fs::read_to_string(&filename).expect("Unable to read file");

    fn extract_words_from_buffer(buffer: &str) -> Vec<&str> {
        let re = Regex::new(r"[\s\n]+").unwrap();
        re.split(buffer.trim()).collect()
    }

    fn build_markov_chain<'a>(words: &'a [&'a str]) -> std::collections::HashMap<&'a str, Vec<&'a str>> {
        let mut markov_chain = std::collections::HashMap::new();

        for i in 0..words.len()-1 {
            let current_word = words[i];
            let next_word = words[i+1];

            markov_chain.entry(current_word).or_insert(Vec::new()).push(next_word);
        }

        markov_chain
    }

    fn generate_markov_expression(markov_chain: &std::collections::HashMap<&str, Vec<&str>>, num_words: usize) -> String {
        let mut expression = String::new();
        let mut current_word = get_random_word(markov_chain.keys().cloned().collect());

        let mut num_words_remaining = num_words;
        while num_words_remaining > 0 {
            expression.push_str(current_word);
            expression.push(' ');

            let empty_vec = Vec::new();
            let next_words = markov_chain.get(current_word).unwrap_or(&empty_vec).to_vec();
            if next_words.is_empty() {
                break;
            }

            current_word = get_random_word(next_words.iter().cloned().collect());
            num_words_remaining -= 1;
        }

        expression.trim().to_string()
    }

    fn get_random_word(words: Vec<&str>) -> &str {
        let mut rng = rand::thread_rng();
        let random_index = rng.gen_range(0..words.len());
        words[random_index]
    }

    fn generate_message_from_file(filename: &str, num_words: usize) -> String {
        let contents = fs::read_to_string(filename).expect("Unable to read file");
        let words = extract_words_from_buffer(&contents);

        let expression = if words.len() > num_words {
            let markov_chain = build_markov_chain(&words);
            generate_markov_expression(&markov_chain, num_words)
        } else if words.len() == num_words {
            words.join(" ")
        } else {
            words[..words.len()-1].join(" ")
        };

        expression
    }

    let num_words = rand::thread_rng().gen_range(1..=5);
    let selected_words = generate_message_from_file(&filename.clone(), num_words);

    selected_words
}

lib.rs:

mod sys_fns;

#[no_mangle]
pub extern "C" fn generate_memes_text(chat_id: *const i8) -> *mut i8 {
    use std::ffi::CString;
    use std::ffi::CStr;
    use std::str;

    let chat_id_str = unsafe { CStr::from_ptr(chat_id).to_bytes() };
    let chat_id_string = str::from_utf8(chat_id_str).unwrap();
    let selected_words = sys_fns::generate_memes_text(chat_id_string);
    let result = CString::new(selected_words).unwrap().into_raw();

    result
}

cargo.toml:

[package]
name = "myproject"
version = "0.1.0"
edition = "2021"

[dependencies]
rand = "0.8"
regex = "1.4"

error:

C:\MeFolder\testing python with rust>rustc --crate-type cdylib myproject/src/lib.rs
error[E0432]: unresolved import `rand`
 --> myproject/src\sys_fns.rs:2:5
  |
2 | use rand::Rng;
  |     ^^^^ maybe a missing crate `rand`?
  |
  = help: consider adding `extern crate rand` to use the `rand` crate

error[E0432]: unresolved import `regex`
 --> myproject/src\sys_fns.rs:3:5
  |
3 | use regex::Regex;
  |     ^^^^^ maybe a missing crate `regex`?
  |
  = help: consider adding `extern crate regex` to use the `regex` crate

error[E0433]: failed to resolve: use of undeclared crate or module `rand`
  --> myproject/src\sys_fns.rs:71:21
   |
71 |     let num_words = rand::thread_rng().gen_range(1..=5);
   |                     ^^^^ use of undeclared crate or module `rand`

error[E0433]: failed to resolve: use of undeclared crate or module `rand`
  --> myproject/src\sys_fns.rs:50:23
   |
50 |         let mut rng = rand::thread_rng();
   |                       ^^^^ use of undeclared crate or module `rand`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.

the code from sys_fns.rs was not written by me. It was translated from Python to Rust by perplexity.ai

I tried to update cargo, wrote commands cargo update, cargo build (after writing all libraries in cargo.toml), but the error is still the same. also I tried to do it through cargo build --release --lib but then the dll file did not appear.


Solution

  • You should never invoke rustc directly, unless you really know what you're doing. Always use cargo.

    If you want a cdylib, say that in Cargo.toml:

    [package]
    name = "myproject"
    version = "0.1.0"
    edition = "2021"
    
    [lib]
    crate-type = ["cdylib"]
    
    [dependencies]
    rand = "0.8"
    regex = "1.4"
    

    Then build the package using cargo build, and check the target/debug folder (or target/release for cargo build --release) for the output file (.dll or .so or .dylib).