我尝试搜索这个但是没有找到任何东西,但是当将int []作为指针传递给本机DLL函数时,是不是仍然存在DLL可以维护对指针的引用的危险,然后尝试"固定"块终止后再次访问它?如果GC移动了您的阵列,这不会导致内存访问错误吗?如果是这样,你怎么解决这个问题?或者这是不太可能的情况?
我有一个带有以下签名的非托管C++函数:
int function(char* param, int ret)
Run Code Online (Sandbox Code Playgroud)
我试图用C#调用它:
unsafe delegate int MyFunc(char* param, int ret);
Run Code Online (Sandbox Code Playgroud)
...
int Module = LoadLibrary("fullpathToUnamanagedDll");
IntPtr pProc = GetProcAddress(Module, "functionName");
MyFunc func = (MyFunc)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(pProc, typeof(MyFunc));
unsafe
{
char* param = null;
int ret = 0;
int result = func(param, ret);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,从旧的C++项目规范中,param为null ,ret为0 都是函数的有效输入.当我尝试调用它似乎工作,但退出时我得到以下错误:
检测到PInvokeStackImbalance
对PInvoke函数'... :: Invoke'的调用使堆栈失去平衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
我已经尝试了几乎任何我能想到的东西(不安全是最后的手段),但是我找不到任何方法来运行该函数而不会得到不平衡的堆栈.还有什么我可以尝试的吗?
背景
我们一直在使用从Joe Duffy的"Windows上的Concurrent Programming"(第149页)中逐字复制的一些代码,这些代码已经生产了一年多.代码(如下所示)在我们的Asp.Net Web应用程序中用于探测是否有足够的堆栈空间.我们的网站允许用户使用简单的专有脚本语言编写自己的网页和控制逻辑脚本 - 用户可以编写令人讨厌的东西并导致堆栈溢出异常,因此我们使用Duffy的代码示例来停止执行错误的脚本无法捕获的StackOverflow异常会占用整个IIS AppPool.这一直很有效.
问题
今天下午突然我们的日志填满了System.OverflowException错误.我们对该服务器的每个请求都有相同的异常.一个快速的IIS重置解决了这个问题.
异常类型:System.OverflowException
异常消息:算术运算导致溢出.
堆栈跟踪:在C:\ SVN\LiquidHtml\Trunk\LiquidHtmlFlowManager\StackManagement.cs中的LiquidHtmlFlowManager.StackManagement.CheckForSufficientStack(UInt64字节)处的System.IntPtr..ctor(Int64值)处:第47行
代码:
public static class StackManagement
{
[StructLayout(LayoutKind.Sequential)]
struct MEMORY_BASIC_INFORMATION
{
public uint BaseAddress;
public uint AllocationBase;
public uint AllocationProtect;
public uint RegionSize;
public uint State;
public uint Protect;
public uint Type;
};
//We are conservative here. We assume that the platform needs a
//whole 16 pages to respond to stack overflow (using an X86/X64
//page-size, not IA64). That's 64KB, which means that for very
//small stacks …Run Code Online (Sandbox Code Playgroud) 我想知道为什么以下发出关于不安全/未检查操作的警告:
Map<String, ProxySession> sessionMap = (Map<String, ProxySession>) se.getSession().getServletContext().getAttribute("myattribute");
Run Code Online (Sandbox Code Playgroud)
演员错了吗?我无法理解我在这里缺少的东西.
PS我不想摆脱警告,我想了解不安全的操作.
谢谢!
这种行为在C#中是否有效
public class MyClass
{
private byte[] data;
public MyClass()
{
this.data = new byte[1024];
}
public unsafe byte* getData()
{
byte* result = null;
fixed (byte* dataPtr = data)
{
result = dataPtr;
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud) 如果我通过在unsafe代码块或方法中使用指针来操作托管C#字符串(例如,反转其字符),那么不安全的实现是否会混淆或破坏.NET字符串池机制?
正在操作的建议字符串是在托管代码中创建的,并传递给不安全的方法进行操作.
此方案的示例:
static void Main(string[] args) {
string s = "this is a test";
UnsafeReverse(s);
Console.WriteLine(s); // displays "tset a si siht"
// assume more managed strings are created and used along with the affected s.
}
static unsafe void UnsafeReverse(string str) {
int len = str.Length;
fixed (char* pStr = str) {
char* p1 = pStr;
char* p2 = pStr + len - 1;
char tmp;
while (p1 < p2) {
tmp = *p1;
*p1 = …Run Code Online (Sandbox Code Playgroud) 我有一个小的C#类,有一些不安全的方法.有没有办法在C#源代码中声明性地指定"/ unsafe"选项(有#pragma或其他任何其他)仅用于类源文件的上下文?我不想为这么小的类创建一个单独的程序集,但我也真的不希望为不安全的代码启用程序集的其余部分(该类目前是其中的一部分).
我正在使用Rust中的原始指针,我正在尝试将一个内存区域从一个地方复制到另一个地方.我已成功复制内存,但只使用for循环并使用指针的偏移量单独复制每个字节.我无法弄清楚如何更有效地做到这一点,即作为一串字节的单个副本,任何人都能指出我正确的方向吗?
fn copy_block_memory<T>(src: *const T, dst: *mut u8) {
let src = src as *const u8;
let size = mem::size_of::<T>();
unsafe {
let bytes = slice::from_raw_parts(src, size);
for i in 0..size as isize {
ptr::write(dst.offset(i), bytes[i as usize]);
}
}
}
Run Code Online (Sandbox Code Playgroud) 我想一个转换Vec的u32s到一个Vec的u8S,最好就地并没有太多的开销.
我目前的解决方案依赖于不安全的代码来重新构建Vec.有没有更好的方法来做到这一点,以及与我的解决方案相关的风险是什么?
use std::mem;
use std::vec::Vec;
fn main() {
let mut vec32 = vec![1u32, 2];
let vec8;
unsafe {
let length = vec32.len() * 4; // size of u8 = 4 * size of u32
let capacity = vec32.capacity() * 4; // ^
let mutptr = vec32.as_mut_ptr() as *mut u8;
mem::forget(vec32); // don't run the destructor for vec32
// construct new vec
vec8 = Vec::from_raw_parts(mutptr, length, capacity);
}
println!("{:?}", vec8) …Run Code Online (Sandbox Code Playgroud)