静态结构与C字符串为LV2插件 [英] static struct with C strings for lv2 plugin

查看:177
本文介绍了静态结构与C字符串为LV2插件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习拉斯特(新手低层次的编程),并要翻译一个小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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆