特别是,我正在考虑这样的场景:
unsafe struct Foo
{
public int Bar;
public Foo* GetMyAddr()
{
fixed (Foo* addr = &this)
return addr;
}
}
Run Code Online (Sandbox Code Playgroud)
假设存储在非托管内存中的Foo,我试图找出在GetMyAddr中评估fixed语句所涉及的内容.我知道作为程序员,这个结构永远不会在托管堆上,我只需要以最有效的方式在非托管内存中获取它的地址.如果在这里使用任何锁定或原子操作,我会特别担心,因为这会使它完全不合适.
这样安全吗:
int main()
{
boost::int16_t t1 = 50000; // overflow here.
boost::uint16_t t2 = (boost::uint16_t)t1;
std::cout << t1 << " " << t2 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
更具体一点:我将这些数据存储在一个表中,该表在模式中使用了签名类型,是否可以安全存储,并以这种方式检索这些数据?
谢谢!
我需要获取任意类型数组的第一个元素的内存地址,该数组存储为Object类型。例如,数组可以是 double[] 或 int[],但在代码中它会被输入为 Object。
虽然获取已知类型数组的地址很简单,但在 C# 中不允许获取对象的地址。是否有一种类型(Object 除外)可以用来存储这样的数组,并且可以更轻松地获取其内存地址?或者有没有办法使用互操作/反射直接访问地址而无需中间数据副本?
请注意,在下面的第二行中,double[] 被存储为一个对象。请注意,在 fixed() 行中,我正在尝试获取 o 的地址,这在 C# 中是不允许的。
提前致谢!
int len=100;
object o = new double [len];
unsafe
{
fixed(int*ptr=&o)
for (int index = 0; index < len; index++)
{
// access data directly to copy it, etc...
}
}
Run Code Online (Sandbox Code Playgroud) 我已经编写了一个函数Reverse来使用不安全上下文中的指针反转.net中的字符串.我喜欢这个.
我分配"问候"和"x"相同的值.我反向问候我的意外x也被逆转了.
using System;
class Test{
private unsafe static void Reverse(string text){
fixed(char* pStr = text){
char* pBegin = pStr;
char* pEnd = pStr + text.Length - 1;
while(pBegin < pEnd){
char t = *pBegin;
*pBegin++ = *pEnd;
*pEnd-- = t;
}
}
}
public static void Main(){
string greet = "Hello World";
string x = "Hello World";
Reverse(greet);
Console.WriteLine(greet);
Console.WriteLine(x);
}
}
Run Code Online (Sandbox Code Playgroud) 有:
[DllImport("OpenAL32.dll")]
static extern void alcOpenDevice(char*[] devicename);
Run Code Online (Sandbox Code Playgroud)
想把这个名字发送给像smth那样的函数:
char[] data = "Hello!".ToCharArray();
char*[] txt = &data;
Run Code Online (Sandbox Code Playgroud)
但得到错误:
无法隐式转换
char[] *为char * []
(有趣的错误,因为C#编译器拒绝char[] *在/ unsafe模式中定义:))
不能获取地址,获取大小,或声明指向托管类型的指针(
char[])
PS
何时char成为管理?这是一个结构,不是吗?
public struct Char : IComparable, IConvertible, IComparable<char>, IEquatable<char>
Run Code Online (Sandbox Code Playgroud)
虽然编译器显示有关声明指向托管类型(char[])的指针的信息.我只能建议当类型是一个数组时,CLR可能会像管理类型一样呈现它,但听起来非常疯狂.
任务是编写一个初始化声明变量的方法,如使用out参数,但使用不安全的上下文.下面的不安全代码适用于C++,但它在C#中打印0.有人可以帮忙吗?
UPD.代码在发布模式下工作.
static void InitBox(out Box box)
{
box = new Box(100);
}
unsafe static void InitBoxUnsafe(Box** box)
{
Box b = new Box(500);
(*box) = &b;
}
static void Main(string[] args)
{
//// The task is to write a code that does the same
// Box box;
// InitBox(out box);
// box.Print();
//// but using unsafe context
//// I wrote this code, but it's not working (output is 0), can anyone tell why?
unsafe
{
Box* pBox;
Box** ppBox …Run Code Online (Sandbox Code Playgroud) 我有类似下面的Rust代码,它可以在某处存储Rust对象(在真实的应用程序中它存储在Lua用户数据中)并在以后检索它(当从Lua调用方法时).
use std::ptr;
struct Bar(u32);
struct Foo<'a> {
subobj: &'a Bar,
}
struct State {
buf: [u8;100],
}
fn stash<T>(state: &mut State, foo: T) {
let p : *mut T = state.buf.as_ptr() as *mut T;
unsafe { ptr::write(p, foo); };
}
fn fetch<T>(state: &mut State) -> &mut T {
let p : *mut T = state.buf.as_ptr() as *mut T;
unsafe { &mut *p }
}
fn main() {
let mut state = State{buf: [0;100]};
// let mut v: Vec<Foo> = …Run Code Online (Sandbox Code Playgroud) 我有一堆外部C函数在C#中成为这样的东西:
public extern static int clGetDeviceInfo(
IntPtr device,
uint param_name,
IntPtr param_value_size,
void* param_value,
out IntPtr param_value_size_ret);
Run Code Online (Sandbox Code Playgroud)
因为有一堆看似相似的函数,我想创建一个读取这些C函数提供的数据的方法.这就是我的用途:
unsafe public static ErrorCode GetInfoString(
IntPtr handle, uint property,
Func<IntPtr, uint, IntPtr, void*, IntPtr, int> infoFunc,
out string value)
{
// reading logic
}
Run Code Online (Sandbox Code Playgroud)
我的问题是C#不允许我使用它void*作为泛型参数Func.有没有解决这个问题的方法?
我既不能改变外部C函数的签名也不能改变C#函数的签名(我正在使用库).
我将原始指针传递给两个不同的闭包,并将原始指针转换为使用引用Box::from_raw(),程序运行正常。
但是,在将原始指针转换为引用后,析构函数应自动调用,如文档所述:
这个函数是不安全的,因为使用不当可能会导致内存问题。例如,如果函数在同一个原始指针上被调用两次,则可能会发生双重释放。
但是,即使在Box::from_raw()两次调用原始指针之后,我也能够访问对 ABC 的引用,并且它工作正常。
struct ABC {}
impl ABC {
pub fn new() -> ABC {
ABC {}
}
pub fn print(&self, x: u32) {
println!("Inside handle {}", x);
}
}
fn main() {
let obj = ABC::new();
let const_obj: *const ABC = &obj;
let handle = |x| {
let abc = unsafe { Box::from_raw(const_obj as *mut ABC) };
abc.print(x);
};
handle(1);
let handle1 = |x| {
let abc = unsafe { Box::from_raw(const_obj as …Run Code Online (Sandbox Code Playgroud) 我正在寻找类似于slice::split_at_mut. 让我们split_at用签名命名它
pub fn split_at<T>(v: Vec<T>, mid: usize) -> (Vec<T>, Vec<T>)
Run Code Online (Sandbox Code Playgroud)
以至于
let v = vec![1, 2, 3, 4];
let (first, second) = split_at(v, 2);
assert_eq!(first, vec![1, 2]);
assert_eq!(second, vec![3, 4]);
Run Code Online (Sandbox Code Playgroud)
该函数不应分配内存,只需将向量一分为二。您无需担心容量,因为结果向量不会被修改。
仅每晚使用的方法Vec::into_raw_parts似乎很有希望,但我在不允许使用此类方法的稳定发布频道上。