You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非托管C DLL结构体封送C#出现访问违规,如何修正对齐?

Fixing Access Violations When Calling Unmanaged C DLL with Function Pointer Struct in C#

Hey there, let's break down why you're hitting those access violations—9 times out of 10 with interop scenarios like this, it's down to mismatched calling conventions, struct layout misalignment, or delegate memory management. Let's walk through the fixes step by step:

1. Fix Delegate Definitions (Move Them Outside the Struct)

Putting delegate types inside the struct works syntactically, but it can cause unexpected layout and marshaling issues with unmanaged code. First, define your delegates outside the struct, and explicitly set their calling convention to match your unmanaged C code (since you're using Cdecl for the DLL function, the function pointers need the same):

// Define delegates with matching calling convention first
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public unsafe delegate void Func1Delegate(void* l, int* data);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public unsafe delegate void Func2Delegate(void* l, int* data);

2. Correct Struct Layout and Members

Next, adjust your struct to match the unmanaged myStructure exactly. The key here is setting the correct packing to avoid memory alignment mismatches—this is a super common cause of access violations:

[StructLayout(LayoutKind.Sequential, Pack = 1)] // Pack=1 matches default C struct alignment (unless your C code uses custom packing)
public unsafe struct myStructure
{
    // Use the delegate types we defined earlier
    public Func1Delegate Func1;
    public Func2Delegate Func2;
}

If your C code uses a custom packing (like #pragma pack(4)), update the Pack value to match that number. This ensures every member in the C# struct lines up perfectly with the unmanaged one in memory.

3. Verify DllImport Declaration

Your functionInterface declaration is mostly right, but double-check the calling convention and make sure you're using unsafe correctly (since we're dealing with pointers):

[DllImport("lib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe void functionInterface(ref myStructure pToStruct);

Also, critical: Make sure your C# project's platform target (x86/x64) matches the architecture of your unmanaged DLL. A 64-bit C# app calling a 32-bit DLL (or vice versa) will almost always throw access violations due to mismatched pointer sizes.

4. Manage Delegate Lifetime (Prevent GC Collection)

If the unmanaged code stores the function pointers for later use (not just during the functionInterface call), your delegates might get garbage collected, leading to random access violations. To fix this, store the delegate instances in a long-lived variable (like a class-level field):

// Keep these alive to prevent GC from collecting the delegates
private static Func1Delegate _func1Instance;
private static Func2Delegate _func2Instance;

public unsafe void CallUnmanagedFunction()
{
    // Initialize delegates and assign them to the struct
    _func1Instance = MyFunc1Implementation;
    _func2Instance = MyFunc2Implementation;

    myStructure structInstance = new myStructure
    {
        Func1 = _func1Instance,
        Func2 = _func2Instance
    };

    // Call the unmanaged function
    functionInterface(ref structInstance);
}

// Your C# implementations of the delegate methods
private unsafe void MyFunc1Implementation(void* l, int* data)
{
    // Add your logic here
}

private unsafe void MyFunc2Implementation(void* l, int* data)
{
    // Add your logic here
}

If the unmanaged code only uses the pointers during the functionInterface call, you can get away with local variables, but storing them long-term is safer for most interop scenarios.

Quick Additional Checks

  • If your C code uses __stdcall instead of cdecl (unlikely here since you specified Cdecl), update the CallingConvention in both delegates and DllImport.
  • Double-check that the void* l parameter in your delegates is handled correctly—don't dereference it unless you know exactly what type of pointer it points to.

内容的提问来源于stack exchange,提问作者Denis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:33:46