我正在开发一个使用一堆WIN32 API调用的项目,需要一些不安全的代码.从最佳实践的角度来看,我应该在使用/ unsafe开关编译的DLL中隔离此代码,同时保持主应用程序的安全吗?
换一种方式.有没有理由不使用/ unsafe开关编译项目?有潜在的风险吗?
我需要在我的C#应用程序中使用这个枚举,但它不会让我使用这些值.当我将类型指定为uint时,我可以使用-1值,当我指定int时,我不能使用最后2个值.有没有办法在这里使用unchecked关键字来允许我定义所有这些值?这些值来自外部源,因此我无法更改它们.
internal enum MyValues : int
{
value1 = -1,
value2 = 0,
value3 = 0x80000000,
value4 = 0xFFFFFFFF
}
Run Code Online (Sandbox Code Playgroud) 我有这个不编译的代码:
public struct MyStruct
{
private fixed uint myUints[32];
public uint[] MyUints
{
get
{
return this.myUints;
}
set
{
this.myUints = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我知道为什么代码不会编译,但我显然是在我太累了想不到的地方,需要一些帮助才能让我朝着正确的方向前进.我有一段时间没有处理不安全的代码,但我很确定我需要做一个Array.Copy(或Buffer.BlockCopy?)并返回一个数组的副本,但是那些不需要我需要的参数.我忘记了什么?
谢谢.
我正在尝试提出一个解决方案,以便我如何将C#中的数组数组传递给本机函数.我已经有了一个函数委托(Marshal.GetDelegateForFunctionPointer),但现在我正在尝试将多维数组(或者更确切地说是一个数组数组)传递给它.
当输入有2个子数组时,此代码示例有效,但我需要能够处理任意数量的子数组.您能想到的最简单的方法是什么?我不想在数组之间复制数据,因为这将在实时循环中发生(我正在与音频效果通信)
public void process(float[][] input)
{
unsafe
{
// If I know how many sub-arrays I have I can just fix them like this... but I need to handle n-many arrays
fixed (float* inp0 = input[0], inp1 = input[1] )
{
// Create the pointer array and put the pointers to input[0] and input[1] into it
float*[] inputArray = new float*[2];
inputArray[0] = inp0;
inputArray[1] = inp1;
fixed(float** inputPtr = inputArray)
{
// C function signature is someFuction(float** input, …Run Code Online (Sandbox Code Playgroud) 我正在研究一种高性能代码,其中该构造是性能关键部分的一部分.
这是在某些部分中发生的情况:
string被"扫描"并且元数据被有效存储.char[][].char[][]应该转移到string[].现在,我知道你可以打电话,new string(char[])但结果必须复制.
为了避免发生这种额外的复制步骤,我想我必须可以直接写入字符串的内部缓冲区.即使这将是一个不安全的操作(我知道这带来了许多影响,如溢出,向前兼容).
我已经看到了实现这一目标的几种方法,但没有一种我真的很满意.
有没有人有关于如何实现这一目标的真实建议?
额外信息:
实际过程不包括转换为char[]必然,它实际上是一个"多子串"操作.像3个索引和它们的长度附加.
该StringBuilder有少数concats的开销太大.
编辑:
由于我要求的一些模糊的方面,让我重新拟定它.
这是发生的事情:
char[].char[]被转换为一个string.我想做的是合并第2步和第3步,结果是:
string(并且GC在过程中可以通过正确使用fixed关键字来保持它的手离开?).需要注意的是,我无法从string []更改输出类型,因为这是一个外部库,项目依赖于它(向后兼容性).
我知道/unsafe在C#中使用标志,你可以使用指针.在C/C++,删除你会用一个指针free(pointer);和delete pointer;分别.但是,如何使用C#指针实现相同的效果?
我想TParent通过使用聚合构建一个包含多个子对象的类.有些对象是独立的,有些也可能依赖于其他孩子.所有子对象都必须具有对父对象的引用.我也想尽可能使用接口.
为此我使用TInterfacedObject的TParent并TAggregatedObject为孩子.由于孩子和父母都知道彼此,我使用弱引用以避免循环依赖.事实上,这种行为已经在中定义TAggregatedObject.当我只使用独立的子对象(TIndependantChild)时,一切正常.
当子对象也依赖于其他孩子时会出现问题,请参阅构造函数TDependantChild.我将引用存储在fChild变量中的另一个子对象中,该变量用[weak]Delphi 10 Berlin中引入的attibute标记.FastMM4报告关机时的内存泄漏:
此外,访问违规会导致System.TMonitor.Destroy加注,但只有当FastMM4处于使用状态并且ReportMemoryLeaksOnShutDown为True时才会发生这种情况.
program Project1;
{$APPTYPE CONSOLE}
uses
FastMM4,
System.SysUtils;
type
IParent = interface
['{B11AF925-C62A-4998-855B-268937EF30FB}']
end;
IChild = interface
['{15C19A4E-3FF2-4639-8957-F28F0F44F8B4}']
end;
TIndependantChild = class(TAggregatedObject, IChild)
end;
TDependantChild = class(TAggregatedObject, IChild)
private
[weak] fChild: IChild;
public
constructor Create(const Controller: IInterface; const AChild: IChild); reintroduce;
end;
TParent = class(TInterfacedObject, IParent)
private
fIndependantChild: TIndependantChild;
fDependantChild: TDependantChild;
public
constructor Create;
destructor Destroy; override; …Run Code Online (Sandbox Code Playgroud) 我将复杂的数字数据填入Vec<f64>表格中的外部C库(不想改变),[i_0_real, i_0_imag, i_1_real, i_1_imag, ...]看起来它Vec<f64>的内存布局Vec<num_complex::Complex<f64>>与长度的一半相同,因为num_complex::Complex<f64>数据结构是内存 -布局与此处[f64; 2]记录的兼容.我想这样使用它而不需要重新分配潜在的大缓冲区.
我假设它是有效的使用from_raw_parts()在std::vec::Vec假一新Vec,是以旧的所有权Vec的记忆(由不忘旧Vec),并使用size / 2和capacity / 2,但是这需要不安全的代码.是否有一种"安全"的方式来进行这种数据重新解释?
它Vec在Rust中作为a分配,Vec<f64>并由C函数.as_mut_ptr()填充使用填充的Vec<f64>.
我目前正在编译不安全的实现:
extern crate num_complex;
pub fn convert_to_complex_unsafe(mut buffer: Vec<f64>) -> Vec<num_complex::Complex<f64>> {
let new_vec = unsafe {
Vec::from_raw_parts(
buffer.as_mut_ptr() as *mut num_complex::Complex<f64>,
buffer.len() / 2,
buffer.capacity() / 2,
)
};
std::mem::forget(buffer);
return …Run Code Online (Sandbox Code Playgroud) 我有一个Haskell项目,该项目非常密集地使用fmap数据结构。为了避免一次又一次遍历相同的数据结构,同时保留自由使用的可能性,我决定使用-type来保护一些较大的结构。fmapCoyoneda
Coyoneda类型具有构造函数Coyoneda :: (x -> y) -> f x -> Coyoneda f y。这个想法是通过参数化,更确切地说是通过共同Yooneda引理,类型f a和Coyoneda f a是同构的,但是Coyoneda类型的优点是它延迟了实际的结构遍历。
例如,在下面的代码中,第一个表达式遍历基础结构3次,而第二个表达式仅遍历一次:
fmap k $ fmap h $ fmap g $ (x :: f a)
lowerCoyoneda $ fmap k $ fmap h $ fmap g $ liftCoyoneda $ (x :: f a)
Run Code Online (Sandbox Code Playgroud)
实际上,第二行减少如下:
lowerCoyoneda $ fmap k $ fmap h $ fmap g $ liftCoyoneda $ x
lowerCoyoneda $ fmap k …Run Code Online (Sandbox Code Playgroud) 我试图理解java unsafe中的两个方法:
public native short getShortVolatile(Object var1, long var2);
Run Code Online (Sandbox Code Playgroud)
VS
public native short getShort(Object var1, long var2);
Run Code Online (Sandbox Code Playgroud)
这有什么真正的区别?这里的挥发性真正起作用了什么?我在这里找到了API doc:http://www.docjar.com/docs/api/sun/misc/Unsafe.html#getShortVolatile( Object,%20long)
但它并没有真正解释两种功能之间的区别.
我的理解是,对于不稳定的,它只对我们写作时很重要.对我来说,我们调用putShortVolatile然后进行读取应该是有意义的,我们可以简单地调用,getShort()因为volatile写入已经保证新值已经刷新到主存储器中.
如果有任何问题,请帮我纠正.谢谢!
unsafe ×10
c# ×6
interop ×2
performance ×2
pointers ×2
.net ×1
aggregation ×1
arrays ×1
bytebuffer ×1
delphi ×1
enums ×1
fixed ×1
haskell ×1
java ×1
memory-leaks ×1
rust ×1
string ×1
volatile ×1
weak ×1