I’m writing rust dll, cdylib which supposed to start new thread and connect to websocket using tokio::tungstenite
i load dll reflectivly into rust program using https://github.com/indygreg/rs-memory-module-sys
dll loads ok, starts threads ok, but when i call connect_async() i get “fatal runtime error: global allocator may not use TLS”
for async capabilities i use async-ffi
dll code:
use std::thread;
use tokio_tungstenite::connect_async;
use std::os::windows::ffi::OsStringExt;
use std::sync::{Arc, Condvar, Mutex};
use std::time::{Duration, Instant};
use tokio::time::{sleep, timeout};
use tokio::sync::{mpsc, oneshot};
use async_ffi::{FfiFuture, FutureExt};
use futures_util::{SinkExt, StreamExt};
use image::{DynamicImage, GenericImageView, ImageBuffer, Rgb, Rgba, RgbaImage};
use scrap::{Capturer, Display};
use std::collections::HashSet;
use std::error::Error;
use std::ffi::{c_char, c_int, CStr, CString, OsString};
async fn socket_start() {
println!("{}", "starting stream");
sleep(Duration::from_millis(5000)).await;
/////Here i get the exception "fatal runtime error: global allocator may not use TLS" :
let (ws_stream, _) = connect_async("ws://localhost:5000/ws").await.expect("Err");
println!("{}", "connected");
}
#[tokio::main]
async fn thread_starter(connid: &str) {
let connid = connid.to_string();
let counterTask = tokio::spawn({
println!("{}",&connid);
socket_start()
}
);
tokio::try_join!(counterTask);
}
#[no_mangle]
pub extern fn show_message( connid: &str) -> FfiFuture<u32>{
let connid = connid.to_string();
let handle = thread::spawn(move || {
println!("{}", "starting stream");
thread_starter( &connid);
});
handle.join();
//this is test of async-ffi
async move {
for i in 0..5 {
println!("3 thread working... {}", i);
std::thread::sleep(std::time::Duration::from_secs(1));
}
let ret:u32=42;
ret
}.into_ffi()
}
reflective load code:
use std::ffi::CString;
use memory_module_sys::{MemoryLoadLibrary, MemoryFreeLibrary, MemoryGetProcAddress};
use std::sync::{Arc, Once};
use tokio::runtime::{Builder, Runtime};
use async_ffi::{BorrowingFfiFuture, FfiFuture, FutureExt};
type ShowMessageFn = extern "C" fn(connid: &str)-> FfiFuture<u32>;
fn main() {
// Path to the DLL file
// Load the DLL from memory
let dll_bytes: &[u8] = include_bytes!("plugin.dll");
unsafe {
let module = MemoryLoadLibrary(dll_bytes.as_ptr() as *const _, dll_bytes.len() as _);
if module.is_null() {
eprintln!("Failed to load DLL from memory.");
return;
}
println!("DLL loaded successfully from memory.");
let func_name = CString::new("show_message").unwrap();
let func_ptr = MemoryGetProcAddress(module, func_name.as_ptr() as *const _);
if func_ptr.is_null() {
eprintln!("Failed to get function address for 'show_message'.");
MemoryFreeLibrary(module);
return;
}
let show_message1: ShowMessageFn = std::mem::transmute(func_ptr);
println!("Calling 'show_message' function from the DLL...");
let connid = "9f4efa63-62e3-4ec9-b033-6a9b80ffce91";
let rt = Runtime::new().expect("err");
rt.block_on(async {
let aa = show_message1(connid).await;
} );
println!("Main thread is not blocked!");
for i in 0..5555 {
println!("Main thread working... {}", i);
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
}
Need to find a way to launch async threads and use tokio::tungstenite or async-tungstenite
Griffin1212 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
5