C#动态调用C DLL时报错“尝试读取或写入受保护的内存”

s_brandy 2009-11-01 02:30:29
各位好,在做程式调试时使用C打个了DLL包,定义如下。然后尝试在C#中做动态调用,代码编译通过,但是在执行时报错:"尝试读取或写入受保护的内存”

DLL 打包时传入一个结构指针,传出一个结构指针。已经调试了几天,还是不知道问题在哪里。请各位多多帮忙!
多谢!!!

// C structure define
struct PinDef {
int Slot;
int Channel;
char PinName[20];
char PinType[5];
char DataType[5];};

struct PtnLst {
char PtnName[15];
int Load; };

struct DCIn {
double VIH;
double VIL; };

struct DCOut {
double VOH;
double VOL;};

struct DCInOut {
double VIH;
double VIL;
double VOH;
double VOL;};

struct DPS {
char PwrPin[5];
double Force;
double Clamp;};

struct DCLevels {
char LevelName[15];
struct DCIn DCLvlInput;
struct DCOut DCLvlOutput;
struct DCInOut DCLvlInOutput;
struct DPS DCLvlDPS; };

struct Period {
char Resource[15];
double Value; };

struct TDomain {
char TimingName[15];
int SlotRef;
double SlotDelay;
struct Period Period; };

struct Timing {
char TimingName[15];
struct TDomain TimingDomain; };

struct DCTest {
char TestName[15];
char Exec[50];
struct Timing TimingBlk;
struct DCLevels DCLevelsBlk;
struct PtnLst Pattern;
struct PinDef SigRefList[255];
char SignalRefStategy[20];
double Force;
double FRange;
double MeaRange;
double Delay;
double Limits;
double TimeOut; };

struct TestResult {
int ErrCode;
char ErrMsg[1024];
char PinName[5];
char TestRslt[10];
double TestVal;};


// C DLL包接口定义
void DummyTemplate2(struct DCTest* pRcvData, struct TestResult* ReturnData) {
double Value = 0.0;
if ( !(strcmp (pRcvData->SigRefList[0].PinName, "DummyPin"))) {
strcpy(ReturnData->TestRslt,"Pass");
Value = 2.0; }
else {
strcpy(ReturnData->TestRslt,"Fail");
Value = 1.0; }

strcpy(ReturnData->PinName, pRcvData->SigRefList[0].PinName);
ReturnData->TestVal = Value;
}

// C# 结构定义
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Etid
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode,Pack = 1)]
public struct PinDef {
public int Slot;
public int Channel;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string PinName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string PinType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string DataType; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PtnLst {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string PtnName;
public int Load; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCIn {
public double VIH;
public double VIL; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCOut {
public double VOH;
public double VOL; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCInOut {
public double VIH;
public double VIL;
public double VOH;
public double VOL; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DPS {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string PwrPin;
public double Force;
public double Clamp; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCLevels {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string LevelName;
public DCIn DCLvlInput;
public DCOut DCLvlOutput;
public DCInOut DCLvlInOutput;
public DPS DCLvlDPS; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Period {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string Resource;
public double Value; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TDomain {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string TimingName;
public int SlotRef;
public double SlotDelay;
public Period Period; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Timing {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string TimingName;
public TDomain TimingDomain; }

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DCTest {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=15)]
public string TestName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=50)]
public string Exec;
public Timing TimingBlk;
public DCLevels DCLevelsBlk;
public PtnLst Pattern;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=255)]
public PinDef[] SigRefList;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)]
public string SignalRefStategy;
public double Force;
public double FRange;
public double MeaRange;
public double Delay;
public double Limits;
public double TimeOut; }

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct TestResult {
public int ErrCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)]
public string ErrMsg;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=5)]
public string PinName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=10)]
public string TestRslt;
public double TestVal; }

public class TestDataContainer {}
}

// -----------------------------------------------
// C# 动态调用DLL
// -----------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;

namespace Etid
{
public partial class ETID : Form
{
public delegate void DummyTemplate2(ref DCTest DcEnv, ref TestResult NodeResult);

DCTest nodeDcTestEnv = new DCTest();
TestResult nodeTestRslt = new TestResult();

// Initialize nodeDcTestEnv
nodeDcTestEnv.TestName = ("DummyTest");
nodeDcTestEnv.Exec = ("DummyTemplate2");
nodeDcTestEnv.TimingBlk = new Timing();
nodeDcTestEnv.TimingBlk.TimingName = ("SIM_Timing");
nodeDcTestEnv.TimingBlk.TimingDomain = new TDomain();
nodeDcTestEnv.TimingBlk.TimingDomain.Period = new Period();
nodeDcTestEnv.TimingBlk.TimingDomain.TimingName = "DomainName";
nodeDcTestEnv.TimingBlk.TimingDomain.SlotDelay = 1.0;
nodeDcTestEnv.TimingBlk.TimingDomain.SlotRef = 5;
nodeDcTestEnv.TimingBlk.TimingDomain.Period.Resource = "Internal";
nodeDcTestEnv.TimingBlk.TimingDomain.Period.Value = 200;

nodeDcTestEnv.DCLevelsBlk = new DCLevels();
nodeDcTestEnv.DCLevelsBlk.DCLvlInput = new DCIn();
nodeDcTestEnv.DCLevelsBlk.DCLvlInput.VIH = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlInput.VIL = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlOutput = new DCOut();
nodeDcTestEnv.DCLevelsBlk.DCLvlOutput.VOH = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlOutput.VOL = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlInOutput = new DCInOut();
nodeDcTestEnv.DCLevelsBlk.DCLvlInOutput.VIH = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlInOutput.VIL = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlInOutput.VOH = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlInOutput.VOL = 0.0;

nodeDcTestEnv.DCLevelsBlk.DCLvlDPS = new DPS();
nodeDcTestEnv.DCLevelsBlk.DCLvlDPS.PwrPin = "VCC";
nodeDcTestEnv.DCLevelsBlk.DCLvlDPS.Force = 0.0;
nodeDcTestEnv.DCLevelsBlk.DCLvlDPS.Clamp = 0.0;
nodeDcTestEnv.DCLevelsBlk.LevelName = ("SIM_Levels");
nodeDcTestEnv.Pattern = new PtnLst();
nodeDcTestEnv.Pattern.PtnName = ("SIM_Pattern");
nodeDcTestEnv.Pattern.Load = 0;
nodeDcTestEnv.SigRefList = new PinDef[255];

PinDef tmpSList = new PinDef();
tmpSList.PinName = ("Du");
tmpSList.Slot = 3;
tmpSList.PinType = "In";
tmpSList.Channel = 6;
tmpSList.DataType = "WDT";

for (int i = 0; i < 255; i++ )
{
nodeDcTestEnv.SigRefList[i] = tmpSList;
}

nodeDcTestEnv.SignalRefStategy = ("Single");
nodeDcTestEnv.Force = 0.02;
nodeDcTestEnv.FRange = 1.0;
nodeDcTestEnv.MeaRange = 200.0;
nodeDcTestEnv.Delay = 5.0;
nodeDcTestEnv.Limits = 110.0;
nodeDcTestEnv.TimeOut = 10.0;

// Initialize nodeDcTestEnv
nodeTestRslt.TestVal = 0.0;
nodeTestRslt.ErrCode = 100;
nodeTestRslt.PinName = "";
nodeTestRslt.ErrMsg = "";
nodeTestRslt.TestRslt = "";

// 建立动态调用环境,都执行通过。 以下3行以说明为主。
// string curDllPath = currentPath + "\\" + "DLL" + "\\" + "DummyTemplate2.dll";
// DynamicLoadDLL dll = new DynamicLoadDLL(curDllPath);
// DummyTemplate2 api = (DummyTemplate2)dll.Invoke("DummyTemplate2", typeof(DummyTemplate2));

// 执行DLL, 执行下面一行时报错
api(ref nodeDcTestEnv, ref nodeTestRslt);
}
}

// -----------------------------------------------
// 编译通过,下面是报错信息。
// -----------------------------------------------
Message "尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
StackTrace "
在 Etid.ETID.DummyTemplate2.Invoke(DCTest& DcEnv, TestResult& NodeResult)\r\n
...全文
360 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
s_brandy 2009-11-05
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 sugar_tiger 的回复:]
不要用C++中特有的数据类型,如CString,像指针这种也要好好处理才行
[/Quote]

还请明示:)
Sugar_Tiger 2009-11-03
  • 打赏
  • 举报
回复
不要用C++中特有的数据类型,如CString,像指针这种也要好好处理才行
s_brandy 2009-11-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dobzhansky 的回复:]
函数调用约定要一致, 看看 C 的函数调用约定是什么, cdel stdcall ...

再就是结构体的大小和内存布局要详细检查.
[/Quote]


这两天在外出差,没来得及回复大家,谢谢大家的热心帮忙.
你说的函数调用约定我会仔细检查一下,等有结果了再反馈你:)
linmingtao 2009-11-02
  • 打赏
  • 举报
回复
up
limeng315 2009-11-02
  • 打赏
  • 举报
回复
代码太长,看得头晕. 一般调用时没有事先分配足够的内存可能会造成这种错误.
netstray 2009-11-02
  • 打赏
  • 举报
回复
ding yi xia
kennie_190602169 2009-11-02
  • 打赏
  • 举报
回复
ding
Gmjinrong 2009-11-02
  • 打赏
  • 举报
回复
检查类型是否匹配
boringame 2009-11-02
  • 打赏
  • 举报
回复
代码发的太长了。。。看晕了。。。
下次记得发重点
mengpaihuai 2009-11-01
  • 打赏
  • 举报
回复
同意楼上的,不过我曾经也遇到过这样的问题?可能是你引用的对象没有得到即时的释放或者未释放完所有的对象。
tangyong12 2009-11-01
  • 打赏
  • 举报
回复
代码太长了,检查一下对应的参数数据类型吧,这种情况很大可能发生在数据类型两边不一致导致的
Dobzhansky 2009-11-01
  • 打赏
  • 举报
回复
函数调用约定要一致, 看看 C 的函数调用约定是什么, cdel stdcall ...

再就是结构体的大小和内存布局要详细检查.
jin20000 2009-11-01
  • 打赏
  • 举报
回复
同意楼上
wuyq11 2009-11-01
  • 打赏
  • 举报
回复
资源占用问题
数组问题
null 值都可能导致,检查代码
oneatree 2009-11-01
  • 打赏
  • 举报
回复
mark
soaringbird 2009-11-01
  • 打赏
  • 举报
回复
CharSet=CharSet.Unicode换成CharSet=CharSet.Ansi试试

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧