我理解指针,并且很少需要在C#代码中使用它们.我的问题是:在一段代码中明确说明"不安全"的原因是什么.另外,为什么必须更改编译器选项以允许"不安全"代码?
结论: CLR(或语言规范)中的内容使得我们不能随时使用指针(很像C和C++)而不必键入"unsafe"并更改编译器选项?
澄清一下:我知道"不安全"和"安全"的代码是什么.这只是一个问题,为什么我们必须做所有额外的工作(好吧,不是那么多)只是为了能够使用这些功能.
我在java.lang.Class #newInstance0中遇到了一些有趣的代码:
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
Run Code Online (Sandbox Code Playgroud)
查看Unsafe.getUnsafe().throwException声明.它看起来像是从一个没有声明它被抛出的方法抛出一个已检查的异常!
他们为什么这么做?
如果Sun开发人员可以使用这种技术,我们也可以这样做吗?
unsafe static void SquarePtrParam (int* p)
{
*p *= *p;
}
Run Code Online (Sandbox Code Playgroud)
VS
static void SquarePtrParam (ref int p)
{
p *= p;
}
Run Code Online (Sandbox Code Playgroud) 我有以下C结构
struct MyStruct {
char chArray[96];
__int64 offset;
unsigned count;
}
Run Code Online (Sandbox Code Playgroud)
我现在有一堆用C语言创建的文件,里面有成千上万的结构.我需要使用C#读取它们,速度是一个问题.
我在C#中做了以下几点
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 108)]
public struct PreIndexStruct {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 96)]
public string Key;
public long Offset;
public int Count;
}
Run Code Online (Sandbox Code Playgroud)
然后我用文件从文件中读取数据
using (BinaryReader br = new BinaryReader(
new FileStream(pathToFile, FileMode.Open, FileAccess.Read,
FileShare.Read, bufferSize)))
{
long length = br.BaseStream.Length;
long position = 0;
byte[] buff = new byte[structSize];
GCHandle buffHandle = GCHandle.Alloc(buff, GCHandleType.Pinned);
while (position < length) {
br.Read(buff, 0, structSize);
PreIndexStruct pis …Run Code Online (Sandbox Code Playgroud) fixed (int* pArray = &array[0])以下示例中的行是否固定整个数组,或者只是array[0]?
int array = new int[10];
unsafe {
fixed (int* pArray = &array[0]) { } // or just 'array'
}
Run Code Online (Sandbox Code Playgroud) 我没有锈的别名规则特别深刻的理解(从我听说他们没有扎实的定义),但我无法理解是什么使这个代码示例中std::slice文档还好.我在这里重复一遍:
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();
unsafe {
for i in 0..x.len() {
*x_ptr.offset(i as isize) += 2;
}
}
assert_eq!(x, &[3, 4, 6]);
Run Code Online (Sandbox Code Playgroud)
我在这里看到的问题是x,作为&mut参考,可以假设编译器是唯一的.xget 的内容经过修改x_ptr,然后通过回读x,我认为没有理由为什么编译器不能假设x没有被修改,因为它从未通过唯一的现有&mut引用进行修改.
那么,我在这里错过了什么?
编译器是否需要假设*mut T可能是别名&mut T,即使通常允许它假设&mut T 永远不会别名别名&mut T?
该unsafe块是否充当某种别名障碍,编译器假定其中的代码可能已修改了范围内的任何内容?
此代码示例是否已损坏?
如果有某种稳定的规则使这个例子没问题,究竟是什么呢?它的范围是多少?我应该担心多少假设破坏unsafeRust代码中的随机事物?
我正在尝试使用C#为学校项目创建缓冲区溢出:
unsafe
{
fixed (char* ptr_str = new char[6] {'H', 'a', 'l', 'l', 'o', ','})
{
fixed (char* ptr_str2 = new char[6] {'W', 'e', 'r', 'e', 'l', 'd'})
{
fixed (char* ptr_str3 = new char[6] {'!', '!', '!', '!', '!', '!'})
{
for (int i = 0; i < 8; i++)
{
ptr_str2[i] = 'a';
}
for (int i = 0; i < 6; i++)
{
this.Label2.Text += ptr_str[i];
this.Label3.Text += ptr_str2[i];
this.Label4.Text += ptr_str3[i];
}
}
}
}
} …Run Code Online (Sandbox Code Playgroud) 我正在努力理解sun.misc.Unsafe的文档 - 我想因为它不适合一般用途,没有人真的为让它可读而烦恼 - 但实际上我真的需要一种方法来找到一个元素的地址一个数组(以便我可以将指针传递给本机代码).有没有人有任何工作代码这样做?它可靠吗?
我有一个关于静态源代码分析的大型项目,一切都成功编译,除了一件事.我在标题中提供了错误消息.令我困惑的一点是,它给出了一条错误信息,说不安全.我认为应该只是警告,而不是错误.顺便说一下,我正在使用Visual Studio 2012.这是我在ctime中得到错误的代码的一部分.如果有人能帮助我克服这个错误,我会很高兴.
void CppCheckExecutor::reportProgress(const std::string &filename, const char stage[], const std::size_t value)
{
(void)filename;
if (!time1)
return;
// Report progress messages every 10 seconds
const std::time_t time2 = std::time(NULL);
if (time2 >= (time1 + 10)) {
time1 = time2;
// current time in the format "Www Mmm dd hh:mm:ss yyyy"
const std::string str(std::ctime(&time2));
// format a progress message
std::ostringstream ostr;
ostr << "progress: "
<< stage
<< ' ' << value << '%';
if (_settings->_verbose)
ostr << " time=" …Run Code Online (Sandbox Code Playgroud) 我使用bindgen板条箱创建从Rust到C库的绑定,但我收到一大堆警告:
warning: `extern` block uses type `u128`, which is not FFI-safe
= note: 128-bit integers don't currently have a known stable ABI
Run Code Online (Sandbox Code Playgroud)
对于这个警告我能做什么?我认为我需要采取一些措施来解决这个问题,或者我可以忽略它吗?