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

.NET Framework 4.8调用返回值为结构体的C函数时触发MarshalDirectiveException的无修改C++代码解决方案咨询

.NET Framework 4.8调用返回值为结构体的C函数时触发MarshalDirectiveException的无修改C++代码解决方案咨询

我现在尝试用C#的DllImport调用C库中的MyCFunction函数,C函数在头文件里的定义如下:

#ifdef WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __attribute__((visibility("default")))
#endif
    
struct Data
{
    bool MyBool;
    const double *Double1;
    const double *Double2;
    const double *Double3;
    const double *Double4;
    const double *Double5;
    const double *Double6;
    const double *Double7;
};

enum EnumType
{
    ENUMVALUE
};

EXPORT Data
MyCFunction(EnumType type);

我的C#代码是这样的:

[StructLayout(LayoutKind.Sequential)]
public struct Data
{
    [MarshalAs(UnmanagedType.I1)]
    public bool MyBool;

    public IntPtr Double1;
    public IntPtr Double2;
    public IntPtr Double3;
    public IntPtr Double4;
    public IntPtr Double5;
    public IntPtr Double6;
    public IntPtr Double7;
}

public enum EnumType
{
    ENUMVALUE
}

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
private static extern Data MyCFunction(EnumType type);

在.NET 8里调用这个方法完全正常,但在.NET Framework 4.8中,会抛出System.Runtime.InteropServices.MarshalDirectiveException: Method's type signature is not PInvoke compatible异常。

因为我不需要封送返回值,只需要把返回的结构体指针传给另一个C++方法,所以我尝试把C#的方法改成这样:

[DllImport(DllName, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
private static extern IntPtr MyCFunction(EnumType type);

但现在又出现了AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.异常,我搞不懂为什么会这样。

我知道最好的解决方案是修改C代码,改成用ref参数而不是返回结构体值,但我没法直接修改这个C库,所以更希望在调用端(C#这边)解决问题。

有没有不需要修改C++代码的解决办法?

备注:内容来源于stack exchange,提问作者MaSiMan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:34:35