在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.   

    http://blog.csdn.net/jame_peng/article/details/4387906你看看这篇文章吧,应该有帮助
      

  2.   

    应该了解一下DLL的接口问题呀
      

  3.   

    public static extern bool ReadCSE(string path, out short[] data, int length);public static extern bool hspecgEcgAutoProcess(IntPtr[] DataIn, ...)
      

  4.   

    改成这样:
    函数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);
      

  5.   

    这个out是不能删的,short[] data这个数组是要最后取函数里的数据结果的
      

  6.   

    我尝试了一下按照这个改动了ReadCSE函数,但是依旧是那个问题,中断调试,运行到这个函数时,就自动退出了。
    我想不明白为什么会出现这个问题在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;
    }
      

  7.   


    short[] data=new short[length]; //这个你写了没有!你既然有VC的这个工程,可以在VC工程这边调试,断点就放在:ReadCSE(LPCTSTR lpszPathName, short *data,long length)的入口处,进去一步一步调试,应该能找到问题!
      

  8.   

    thanks for your help我没有dll的工程,只有这个ReadCSE函数的代码
    不过有dll工程的话,我在C#工程里里用P/Invoke调用dll的函数,中断中断执行时,也进不去vc的工程去吧那个dll在vc的测试程序里可以正常执行,用p/invoke调用时才出错
    ps.short[] data=new short[length]这个有写的
      

  9.   

    “我没有dll的工程,只有这个ReadCSE函数的代码”,这个dll是第三方的?
    实在没有,可以在C#这边的工程属性:调试-> 勾上启动非托管代码调试,
    看看能否进入VC代码!还有,你有没有VC的Demo,有的画,把VC的Demo使用这个函数的代码贴出来,
    同时把C#这边使用代码贴出来,我对比看看
      

  10.   


    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];
      

  11.   

    m_data的值是在ReadCSE那个函数里赋值的,之前没有初始化
      

  12.   

    net工程属性:调试->勾上非托管代码调试,看看能否进入VC代码?
      

  13.   

    进不去的,你先前说过,我有试过,勾选后,IDE没反应。我版本是vs2005anyway,thanks
      

  14.   

    那你只有把这个dll的VC工程拿过来测试了,想不出更好的办法了
      

  15.   

    可是拿到了dll的vc工程,我在c#里启动程序中断调试,也进不去vc的代码段啊
    so,很尴尬
      

  16.   

    这个没可能!告诉你做法:
    你VC编译的Debug版本的dll,跟你在对C#中使用[DllImport("hspecgEcgDiag.dll")],保证是同一个目录的!用我前面跟你说的两种办法,都可以进入VC工程!不过,为了更好测试这个问题,建议你在VC这边的dll工程启动,把net的exe做为它的外挂程序,明白没有
      

  17.   

    不是很明白这个具体做法。
    不过我会去试一试thanks