我正在从我的 C# 托管代码调用一些C++本机代码。当从 64 位或 AnyCPU 编译的应用程序加载此 dll 时,一切都完美运行。当它从 32 位应用程序加载时,我在调用 InitializeSecurityContextW 方法时收到 AccessViolationException。本机方法的定义如下:
[DllImport(SECUR32DLL, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
private static extern StatusEnum InitializeSecurityContextW(
[In] ref HandleStruct handle1,
[In] IntPtr handle2,
[In] String str,
[In] uint flags1,
[In] uint reserved1,
[In] uint flags2,
[In] IntPtr bufferDesc,
[In] uint reserved2,
[In, Out] ref HandleStruct handleOut,
[In, Out] BufferDescriptor bufferDescOut,
[Out] out uint flagsOut,
[Out] out long expiryOut);
使用以下结构和枚举:
public struct HandleStruct
{
private IntPtr Low;
private IntPtr High;
public bool IsZero
{
return Low == IntPtr.Zero && High == IntPtr.Zero;
}
}
private enum StatusEnum {
// Values here.
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
private struct BufferDescriptor
{
public uint Version;
public uint Count;
public IntPtr BufferArray;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
private struct Buffer
{
public uint Size;
public uint Type;
public IntPtr Data;
}
(简化的)调用代码是:
Buffer[] bufferOut = new Buffer[1];
bufferOut[0].Size = 0;
bufferOut[0].Type = 2; // Token type
bufferOut[0].Data = IntPtr.Zero; // I'm asking the server to allocate this memory (unmanaged).
GCHandle bufferOutPtr = GCHandle.Alloc(bufferOut, GCHandleType.Pinned);
BufferDescriptor bufferDescOut = new BufferDescriptor();
bufferDescOut.Count = 1;
bufferDescOut.Version = 0; // Version number
bufferDescOut.BufferArray = bufferOutPtr.AddrOfPinnedObject();
uint flags1 = // Some flags here including asking the server to allocate memory;
uint flags2 = 0; //data representation
uint flagsOut;
long expiry;
StatusEnum status = InitializeSecurityContextW(
ref handle1, // From calling method
IntPtr.Zero, // Null for this call
str, // From calling method
flags1,
0,
flags2,
IntPtr.Zero, // Null for this call
0,
ref handleOut, // From calling method, currently handleOut.IsZero == true
bufferDescOut,
out flagsOut,
out expiry);
// Clean up code, never reached.
为什么会发生这种情况,为什么只有 32 位?
我需要固定我的输出缓冲区描述符并传递地址而不是整个结构。