从 C# 调用 C dll 时出现 AccessViolationException

问题描述

我正在尝试为 C dll 创建一个包装器,以便在 C# 中使用它。我没有dll的源代码。 我在使用一种方法时遇到问题,该方法在执行时给我“System.AccessViolationException:'尝试读取或写入受保护的内存。这通常表明其他内存已损坏'”。我试图在网上搜索同样的问题,但我没有找到我的代码有什么问题。

给出问题的方法如下:

C:

L3B6_API L3B6_ERR_t STDCALL L3B6_ActivateBoot(int nodeid,unsigned cpunum,unsigned ms_timeout,const char * devicenames,A * dev_param);

我在 C# 中创建的包装器是这样的:

[DllImport("L3B6.dll",EntryPoint = "L3B6_ActivateBoot")]
return: MarshalAs(UnmanagedType.I4)]
static extern L3B6ErrorCode ActivateBoot(
                int nodeid,uint cpunum,uint msTimeout,[MarshalAs(UnmanagedType.LPStr)]
                string deviceNames,ref A devParams
                );

其中 L3B6ErrorCode 是我创建的枚举,但它没有出现任何问题(我将它用于其他有效的方法)。 我觉得问题出在结构A上,原来的结构是这样的:

struct A
{
    unsigned char blv;
    unsigned char cpunum;
    unsigned char nodeid;
    unsigned char hwverA;
    unsigned char hwverB;
    unsigned char hwverC;
    unsigned char hwverD;
    unsigned char cputype;
    unsigned char hwcode;
    B memini_devrec;
};

struct B
{
    unsigned hwCode;                       
    unsigned cpuCode;                      
    unsigned dualcpu;                      
    unsigned cpuNumber;                    
    unsigned internalFlashStart;           
    unsigned internalFlashEnd;             
    unsigned externalFlashAccess;          
    unsigned externalFlashStart;           
    unsigned externalFlashEnd;             
    unsigned isResetVectorSpecified;       
    unsigned resetVectors;                 
    char bootName[32];                     
    unsigned isS19toPhyConversionAllowed;  
    unsigned noFlashPaging;                
    char deviceName[32];                   
    char cpuName[32];                      
};

我创建的对应结构如下:

    [StructLayout(LayoutKind.Sequential)]
    public struct A
    {
        public byte bootloaderversion;
        public byte cpuNum;
        public byte nodeId;
        public byte hwVerA;
        public byte hwVerB;
        public byte hwVerC;
        public byte hwVerD;
        public byte cpuType;
        public byte hwCode;
        public B meminiDeviceRecord;
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct B
    {
        public uint hwCode;
        public uint cpuCode;
        [MarshalAs(UnmanagedType.Bool)]
        public bool dualcpu;
        public uint cpuNumber;
        public uint internalFlashStart;
        public uint internalFlashEnd;
        public uint externalFlashAccess;
        public uint externalFlashStart;
        public uint externalFlashEnd;
        [MarshalAs(UnmanagedType.Bool)]
        public bool isResetVectorSpecified;
        public uint resetVectors;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 32)]
        public string bootName;
        [MarshalAs(UnmanagedType.Bool)]
        public bool isS19toPhyConversionAllowed;
        [MarshalAs(UnmanagedType.Bool)]
        public bool noFlashPaging;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 32)]
        public string deviceName;
        [MarshalAs(UnmanagedType.ByValTStr,SizeConst = 32)]
        public string cpuName;
    };

我在另一种需要填充它的方法中使用了结构 B 并且没有任何问题,所以我认为问题出在 A 结构中,但我不明白我做错了什么。我认为问题在于该结构,因为另一种将该结构作为参数的方法也给了我同样的例外。我检查了 C 和 C# 中结构的大小,结果是一样的。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)