静态结构与C字符串为LV2插件 [英] static struct with C strings for lv2 plugin
问题描述
我想学习拉斯特(新手低层次的编程),并要翻译一个小LV2放大器(音频)插件amp.c(的 C- code )从C生锈。事实上,我得到它的工作(这里),但是当主机终止,Valgrind的说
在1块64个字节肯定是失去了。我想我知道为什么会这样,但我不知道如何解决它。
I'm trying to learn Rust (newbie in low level programming), and want to translate a tiny lv2 amplifier (audio) plugin "amp.c" (C-code) from C to Rust. I actually got it working (here), but when the host terminates, valgrind says that " 64 bytes in 1 blocks are definitely lost". I think I know why this happens, but I don't know how to fix it.
累的读书之前,这里是最后一个问题:
Before you get tired of reading, here is the final question:
我如何静态分配,它包含一个C字符串结构?
How do I statically allocate a struct that contains a C string?
和这里的介绍:
为什么会发生(我认为):
主机负载库和调用lv2_descriptor()
Why it happens (I think): Host loads the library and calls lv2_descriptor()
const LV2_Descriptor*
lv2_descriptor()
{
return &descriptor;
}
返回一个指向类型LV2_Descriptor的静态分配结构,
which returns a pointer to a STATICALLY allocated struct of type LV2_Descriptor,
static const LV2_Descriptor descriptor = {
AMP_URI,
...
};
其被定义为
typedef struct _LV2_Descriptor {
const char * URI;
...
} LV2_Descriptor;
为什么静态分配的?在amp.c它说:
Why is it statically allocated? In the amp.c it says:
这是最好的静态定义的描述,以避免泄漏内存
和非便携式共享库的构造函数和析构函数清理
正确。
It is best to define descriptors statically to avoid leaking memory and non-portable shared library constructors and destructors to clean up properly.
不过,我翻译lv2_descriptor()来锈为:
However, I translated lv2_descriptor() to Rust as:
#[no_mangle]
pub extern fn lv2_descriptor(index:i32) -> *const LV2Descriptor {
let s = "http://example.org/eg-amp_rust";
let cstr = CString::new(s).unwrap();
let ptr = cstr.as_ptr();
mem::forget(cstr);
let mybox = Box::new(LV2Descriptor{amp_uri: ptr}, ...);
let bxptr = &*mybox as *const LV2Descriptor;
mem::forget(mybox);
return bxptr
}
所以它不是静态分配的,我从来没有免费的,这是我猜的valgrind为什么抱怨?
So it's not statically allocated and I never free it, that's I guess why valgrind complains?
我怎么试图解决它?
我试图做同样的事情在鲁斯特的C- code呢,即静态分配的结构(lv2_descriptor中的之外的())。我们的目标是要到LV2库完全兼容,即......以避免内存泄漏......等等,因为它在报价说,对不对?所以,我想是这样的:
How am I trying to solve it? I'm trying to do the same thing in Rust as the C-code does, i.e. statically allocate the struct (outside of lv2_descriptor()). The goal is to be fully compatible to the lv2 library, i.e "...to avoid leaking memory..." etc., as it says in the quote, right? So I tried something like:
static ptr1: *const u8 = (b"example.org/eg-amp_rust\n\0").as_ptr();
static ptr2: *const libc::c_char = ptr1 as *const libc::c_char;
static desc: LV2Descriptor = LV2Descriptor{amp_uri: ptr2, ...};
但是,这并不编译,有喜欢
But this does not compile, there are error messages like
src/lib.rs:184:26: 184:72 error: the trait `core::marker::Sync` is not implemented for the type `*const u8` [E0277]
src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:184:26: 184:72 note: `*const u8` cannot be shared between threads safely
src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:184:26: 184:72 error: static contains unimplemented expression type [E0019]
src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr();
的具体问题/问题:
我如何静态分配,它包含一个C字符串结构?
How do I statically allocate a struct that contains a C string?
推荐答案
简短的回答是,你现在不知道。未来可能生锈将获得这种能力。
The short answer is, you don't for now. Future Rust will probably gain this ability.
你能做什么,是静态分配包含空指针的结构体,当你调用该函数设置这些空指针到一些有用的东西。锈病静态MUT
。它需要的不安全code 是不会线程是在所有的,是(据我所知)视为 code气味。
What you can do, is statically allocate a struct that contains null pointers, and set those null pointers to something useful when you call the function. Rust has static mut
. It requires unsafe code, is not threadsafe at all and is (to the best of my knowledge) considered a code smell.
就在这里我认为这是一个解决办法的事实,有没有办法把一个&放大器; [T]
到 * const的牛逼
在静态的。
Right here I consider it a workaround to the fact that there is no way to turn a &[T]
into a *const T
in a static.
static S: &'static [u8] = b"http://example.org/eg-amp_rust\n\0";
static mut desc: LV2Descriptor = LV2Descriptor {
amp_uri: 0 as *const libc::c_char, // ptr::null() isn't const fn (yet)
};
#[no_mangle]
pub extern fn lv2_descriptor(index: i32) -> *const LV2Descriptor {
let ptr = S.as_ptr() as *const libc::c_char;
unsafe {
desc.amp_uri = ptr;
&desc as *const LV2Descriptor
}
}
这篇关于静态结构与C字符串为LV2插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!