在C++写的dll中有如下几个函数,
1.
extern "C" __declspec(dllimport) bool ReadCSE(char* lpszPathName, short *data,long length)
2.
bool hspecgEcgAutoProcess(short **DataIn,short Seconds,short Samplerate,double uVperbit);
解释
函数1.char* lpszPathName为字符串,是一个文件名路径,short* data为short型数组
作用是把给定路径的文件中的数据,读取后存放在data数组中
函数2.short **DataIn为一个二维数组我在C#中写法如下
函数1.
[DllImport("hspecgEcgDiag.dll")]
public static extern bool ReadCSE(string lpszPathName, out short[] data, long length);
函数2.
[DllImport("hspecgEcgDiag.dll")]
public static extern bool hspecgEcgAutoProcess(ref short[,] DataIn, short Seconds, short Samplerate, double uVperbit);描述
1.
dll的调用应该是没有问题的,该dll中另外一个函数是可以调用执行的,但是这两个函数执行时出错了
我中断后,逐句执行到函数1时,马上就直接结束程序,停止调试了
大致如下
long length=100;
short[] data=new short[length];
ReadCSE("000.ex",data,length);2.
中断逐步执行到函数2时,提示错误:在未知模块中出现异常请问如上两个问题,大概是怎么一回事?
1.
extern "C" __declspec(dllimport) bool ReadCSE(char* lpszPathName, short *data,long length)
2.
bool hspecgEcgAutoProcess(short **DataIn,short Seconds,short Samplerate,double uVperbit);
解释
函数1.char* lpszPathName为字符串,是一个文件名路径,short* data为short型数组
作用是把给定路径的文件中的数据,读取后存放在data数组中
函数2.short **DataIn为一个二维数组我在C#中写法如下
函数1.
[DllImport("hspecgEcgDiag.dll")]
public static extern bool ReadCSE(string lpszPathName, out short[] data, long length);
函数2.
[DllImport("hspecgEcgDiag.dll")]
public static extern bool hspecgEcgAutoProcess(ref short[,] DataIn, short Seconds, short Samplerate, double uVperbit);描述
1.
dll的调用应该是没有问题的,该dll中另外一个函数是可以调用执行的,但是这两个函数执行时出错了
我中断后,逐句执行到函数1时,马上就直接结束程序,停止调试了
大致如下
long length=100;
short[] data=new short[length];
ReadCSE("000.ex",data,length);2.
中断逐步执行到函数2时,提示错误:在未知模块中出现异常请问如上两个问题,大概是怎么一回事?
outshort[] data, int length);public static extern bool hspecgEcgAutoProcess(IntPtr[] DataIn, ...)函数1.
[DllImport("hspecgEcgDiag.dll")]
[return : MarshalAs( UnmanagedType.I1)]
public static extern bool ReadCSE(string lpszPathName, [In,Out]short[] data, int length);
函数2.
[DllImport("hspecgEcgDiag.dll")]
[return : MarshalAs( UnmanagedType.I1)]
public static extern bool hspecgEcgAutoProcess(IntPtr DataIn, short Seconds, short Samplerate, double uVperbit);
我想不明白为什么会出现这个问题在ReadCSE的原函数内容大致如下BOOL ReadCSE(LPCTSTR lpszPathName, short *data,long length)
{
FILE *EcgFileHandle; unsigned short data1[1500],data2,data3;
long datacount=0; EcgFileHandle=fopen(lpszPathName,"rb");
if(EcgFileHandle)
{
memset(data,0,length*sizeof(short));
fseek(EcgFileHandle,3000,SEEK_SET); //第1路信号
// fseek(EcgFileHandle,0,SEEK_SET); //第1路信号
while(!feof(EcgFileHandle))
{
fread(data1,2,1500,EcgFileHandle); //每次read一个数据包
for(int i=0;i<1500;i++) {
data2=data1[i]<<8;
data2&=0xff00;
data3=data1[i]>>8;
data3&=0x00ff;
data1[i]=data2+data3;
}
if((datacount<10)&(datacount>=0))
{ for(int j=0;j<500;j++) { //为I、II、III
*(data +8*j+datacount*4000) = data1[3*j];
*(data + 1+8*j+datacount*4000) = data1[1+3*j];
// *(Data + 2+8*j+datacount*4000) = data1[2+3*j];
}
datacount++;
}
//0-9为I、II、III,10-19为avR、avL、avF, 20-29为V1、V2、V3,30-39为V4、V5、V6,40-49为x、y、z
else {
if((datacount<20)&(datacount>=10)) { //avR、avL、avF
datacount++;
}
else {
if((datacount<30)&(datacount>=20)) { //V1 V2 V3
for(int j=0;j<500;j++) {
*(data +2+8*j+(datacount-20)*4000) = data1[3*j];
*(data +3+8*j+(datacount-20)*4000) = data1[1+3*j];
*(data +4+8*j+(datacount-20)*4000) = data1[2+3*j];
}
datacount++;
}
else{
if((datacount<40)&(datacount>=30)) {
for(int j=0;j<500;j++) {
*(data +5+8*j+(datacount-30)*4000) = data1[3*j];
*(data +6+8*j+(datacount-30)*4000) = data1[1+3*j];
*(data +7+8*j+(datacount-30)*4000) = data1[2+3*j];
}
datacount++;
}
else
{
fclose(EcgFileHandle);
break;
}
}
}
}
}
fclose(EcgFileHandle);
return TRUE;
}
return FALSE;
}
short[] data=new short[length]; //这个你写了没有!你既然有VC的这个工程,可以在VC工程这边调试,断点就放在:ReadCSE(LPCTSTR lpszPathName, short *data,long length)的入口处,进去一步一步调试,应该能找到问题!
不过有dll工程的话,我在C#工程里里用P/Invoke调用dll的函数,中断中断执行时,也进不去vc的工程去吧那个dll在vc的测试程序里可以正常执行,用p/invoke调用时才出错
ps.short[] data=new short[length]这个有写的
实在没有,可以在C#这边的工程属性:调试-> 勾上启动非托管代码调试,
看看能否进入VC代码!还有,你有没有VC的Demo,有的画,把VC的Demo使用这个函数的代码贴出来,
同时把C#这边使用代码贴出来,我对比看看
BOOL CTestvhEcgDiagDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE; // TODO: 在此添加您专用的创建代码
if(!ReadCSE(lpszPathName, m_data,m_length)) return FALSE;
short i;
for(i=0;i<12;i++) if(!m_templ[i]) {delete[]m_templ[i]; m_templ[i]=NULL;} char szPath[_MAX_DIR],szDir[_MAX_DIR],szDrive[_MAX_DRIVE];
::GetModuleFileName(AfxGetInstanceHandle(),szPath,_MAX_PATH);
_splitpath_s(szPath,szDrive,_MAX_DRIVE,szDir,_MAX_DIR,NULL,0,NULL,0); CString strXml(szDrive),tmp(lpszPathName);
i=tmp.ReverseFind('\\');
if(i>=0) tmp=tmp.Right(tmp.GetLength()-i-1); tmp.ReleaseBuffer();
strXml+=szDir; strXml+=tmp; strXml+=".xml"; short *data[8];
long length=m_length/8;
short fs=500,Seconds=length/fs;
double uVpb=1; long j,k;
for(i=0;i<8;i++) data[i]=new short[length]; for(j=k=0;j<length;j++) {
for(i=0;i<8;i++) data[i][j]=m_data[k++];
}
hspecgBeginEcgDiag(); //开始诊断 hspecgEcgAutoProcess(data,Seconds,fs,uVpb);//自动分析
hspecgEcgCode('M',35); //诊断编码。'M' for Male, 'F' for Female
hspecgDiagXML((char *)(LPCTSTR)strXml,"","",""); m_templen=hspecgGetTemplLength();
if(m_templen>0) {
for(i=0;i<12;i++) {
m_templ[i]=new short[m_templen];
short *templ=hspecgGetTemplData(i);
memcpy(m_templ[i],templ,m_templen*sizeof(short));
}
} hspecgEndEcgDiag(); //结束诊断
for(i=0;i<8;i++) delete[]data[i];
return TRUE;
}这是vc的demo里使用这个ReadCSE函数的地方,在第6行,之后就没有使用,后边的代码不用看了,是处理读取出来的m_data数据的了。
m_length,m_data的定义如下
fs=500;
seconds=10;
m_length=fs*seconds*8;
m_data=new short[m_length];
so,很尴尬
你VC编译的Debug版本的dll,跟你在对C#中使用[DllImport("hspecgEcgDiag.dll")],保证是同一个目录的!用我前面跟你说的两种办法,都可以进入VC工程!不过,为了更好测试这个问题,建议你在VC这边的dll工程启动,把net的exe做为它的外挂程序,明白没有
不过我会去试一试thanks