c# 调用dll问题

tonnycao 2010-01-22 11:27:38
c#调用dll,dll函数原型中参数中含有结构体,该结构体中又含有结构体,在c#中如何定义呢?dll中结构体如下
struct stDLL_CHANNEL_SENSOR_LIST {
int nSensorCount;
float fWaveLengthVec[30];
float fPowerDBVec[30];
};
struct stDLL_CHANNEL_LIST {
int nChNum;
int nFreq;
stDLL_CHANNEL_SENSOR_LIST tSensorListVec[150];
};
...全文
3284 78 打赏 收藏 转发到动态 举报
写回复
用AI写文章
78 条回复
切换为时间正序
请发表友善的回复…
发表回复
kankanbiao 2011-03-22
  • 打赏
  • 举报
回复
System.ExecutionEngineException
这个问题是怎么解决的呀?楼主不厚道啊,呵呵
mattertome 2011-03-16
  • 打赏
  • 举报
回复
遇到同样的问题
xiaowuge1314 2010-08-12
  • 打赏
  • 举报
回复
xuexi
xingyuebuyu 2010-02-25
  • 打赏
  • 举报
回复
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PerChannel)* 11)

你没有将ptArray[0]地址所对应的空间释放啊,运行次数越多程序占的内存越大。你直接将申请到的空间地址存到pt中就可以了啊,用完释放就可以了
tonnycao 2010-02-25
  • 打赏
  • 举报
回复
上面问题解决了我就结贴了,很长时间了,谢谢各位了啊
tonnycao 2010-02-25
  • 打赏
  • 举报
回复
现在代码如下倒是可以取得结果了!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace ReadDSPtest
{
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
internal struct SensorList
{
internal int nSensorCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
internal float[] fWaveLengthVec;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
internal float[] fPowerDBVec;


}
[StructLayout(LayoutKind.Sequential)]
internal struct PerChannel
{
internal int nChNum;
internal int nFreq;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 150)]
internal SensorList[] tSensorListVec;


}




[DllImport("ReadData.dll")]
public static extern void SEN_Init();

[DllImport("ReadData.dll")]
public static extern void SEN_Close();

[DllImport("ReadData.dll")]
public static extern int SEN_ReadDSPData(IntPtr channels);

[DllImport("ReadData.dll")]
public static extern bool SEN_IsConnected();

[DllImport("ReadData.dll")]
public static extern int SEN_SendParaData();



public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
try
{
SEN_Init();

btnStartRun.Enabled = true;

}
catch (Exception ecc)
{

MessageBox.Show(ecc.Message);
}

}

private void btnStartRun_Click(object sender, EventArgs e)
{
try
{
if (!SEN_IsConnected())
{
MessageBox.Show("连接失败!");
return;
}
if (SEN_SendParaData() != 0)
{
MessageBox.Show("发送参数失败!");
return;
}
PerChannel[] channelList = new PerChannel[11];
for (int i = 0; i < channelList.Length; i++)
{
channelList[i] = new PerChannel();

}

IntPtr[] ptArray = new IntPtr[1];

ptArray[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PerChannel)) * 11);

IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * 1);

Marshal.Copy(ptArray, 0, pt, 1);

// 获取数据
SEN_ReadDSPData(pt);
//执行到这儿出错信息An unhandled exception of type 'System.ExecutionEngineException' occurred in Unknown Module.

// 得到结果分析
for (int i = 0; i < channelList.Length; i++)
{
channelList[i] = (PerChannel)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(PerChannel))), typeof(PerChannel));
}

// 清理内存
//Marshal.DestroyStructure(pt, typeof(PerChannel));
Marshal.FreeHGlobal(pt);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
SEN_Close();
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SEN_Close();
}
}
}
但是有时候会有这样的出错:
An unhandled exception of type 'System.ExecutionEngineException' occurred in Unknown Module.
xingyuebuyu 2010-02-25
  • 打赏
  • 举报
回复
引用 60 楼 tonnycao 的回复:
现在程序如下:例子程序是每秒1次的执行读取数据,处理数据的。我现在只是先看看能不能得到程序所以用按钮点击一下,读取数据。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace ReadDSPtest
{
    public partial class Form1 : Form
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct SensorList
        {
            public int nSensorCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30 )]
            public float[] fWaveLengthVec;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30 )]
            public  float[] fPowerDBVec;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct PerChannel
        {
            public int nChNum;
            public int nFreq;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 150 )]
            public SensorList[] tSensorListVec;

        }
   

        [DllImport("ReadData.dll")]
        public static extern void SEN_Init();

        //[DllImport("ReadData.dll")]
        //public static extern int SEN_Close();

        [DllImport("ReadData.dll")]
        public static extern void SEN_ReadDSPData(PerChannel[] channels);

        [DllImport("ReadData.dll")]
        public static extern bool SEN_IsConnected();

        [DllImport("ReadData.dll")]
        public static extern int SEN_SendParaData();

       
                                   
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                SEN_Init();

                btnStartRun.Enabled = true;

            }
            catch (Exception ecc)
            {

                MessageBox.Show(ecc.Message);
            }

        }

        private void btnStartRun_Click(object sender, EventArgs e)
        {
            try
            {
                PerChannel[] channelList = new PerChannel[11];

                if (!SEN_IsConnected())
                {
                    MessageBox.Show("连接失败!");
                    return;
                }
                if (SEN_SendParaData() != 0)
                {
                    MessageBox.Show("发送参数失败!");
                    return;
                }
                for (int i = 0; i < channelList.Length; i++)
                {
                    channelList[i] = new PerChannel();
                    //channelList[i].tSensorListVec = new SensorList[150];

                }

                SEN_ReadDSPData( channelList);
             
                MessageBox.Show("dddd!");
               
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                MessageBox.Show(ex.Message);
            }
        }
    }
}



调用成功后channelList中是否有数据,是否只是错误的数据,如果只是错误的数据那可能就是结构体定义的问题,要考虑数据的内存对齐问题;你对比一下SensorList和PerChannel的结构体大小,要确保在C#和VC++中的大小是一致的,想1楼那样修改结构体的Pack大小,直到两边的结果一样。
tonnycao 2010-02-25
  • 打赏
  • 举报
回复
谢谢所有人!终于可以得到数据正常运行了!
abaochen 2010-02-24
  • 打赏
  • 举报
回复
是用一楼的方法定义的结构。能不能c++里的结构体,在c#中用class来改写呢?
tonnycao 2010-02-24
  • 打赏
  • 举报
回复
结构体定义
#define DLL_MAX_SENSOR_COUNT 30
#define DLL_MAX_FREQ 150
#define DLL_MAX_CHANNEL_COUNT 11

struct stDLL_CHANNEL_SENSOR_LIST {
int nSensorCount;
float fWaveLengthVec[DLL_MAX_SENSOR_COUNT];
float fPowerDBVec[DLL_MAX_SENSOR_COUNT];
};
struct stDLL_CHANNEL_LIST {
int nChNum;
int nFreq;
stDLL_CHANNEL_SENSOR_LIST tSensorListVec[DLL_MAX_FREQ];
};

读取数据函数
extern "C"
__declspec(dllexport)int WINAPI SEN_ReadDSPData(stDLL_CHANNEL_LIST pChannelData[11])

大家再看看,我在c#里该如何定义和调用
tonnycao 2010-02-24
  • 打赏
  • 举报
回复
终于找到dll的源代码了,c++我不熟,一会贴出相关代码
tonnycao 2010-02-24
  • 打赏
  • 举报
回复
没人回答了啊?帮帮忙大家。谢谢
呆小丁 2010-02-23
  • 打赏
  • 举报
回复
对我有用 顶了 很有想、用啊 和
tonnycao 2010-02-23
  • 打赏
  • 举报
回复
现在程序如下:例子程序是每秒1次的执行读取数据,处理数据的。我现在只是先看看能不能得到程序所以用按钮点击一下,读取数据。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace ReadDSPtest
{
public partial class Form1 : Form
{
[StructLayout(LayoutKind.Sequential)]
public struct SensorList
{
public int nSensorCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30 )]
public float[] fWaveLengthVec;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30 )]
public float[] fPowerDBVec;
}
[StructLayout(LayoutKind.Sequential)]
public struct PerChannel
{
public int nChNum;
public int nFreq;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 150 )]
public SensorList[] tSensorListVec;

}


[DllImport("ReadData.dll")]
public static extern void SEN_Init();

//[DllImport("ReadData.dll")]
//public static extern int SEN_Close();

[DllImport("ReadData.dll")]
public static extern void SEN_ReadDSPData(PerChannel[] channels);

[DllImport("ReadData.dll")]
public static extern bool SEN_IsConnected();

[DllImport("ReadData.dll")]
public static extern int SEN_SendParaData();



public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
try
{
SEN_Init();

btnStartRun.Enabled = true;

}
catch (Exception ecc)
{

MessageBox.Show(ecc.Message);
}

}

private void btnStartRun_Click(object sender, EventArgs e)
{
try
{
PerChannel[] channelList = new PerChannel[11];

if (!SEN_IsConnected())
{
MessageBox.Show("连接失败!");
return;
}
if (SEN_SendParaData() != 0)
{
MessageBox.Show("发送参数失败!");
return;
}
for (int i = 0; i < channelList.Length; i++)
{
channelList[i] = new PerChannel();
//channelList[i].tSensorListVec = new SensorList[150];

}

SEN_ReadDSPData( channelList);

MessageBox.Show("dddd!");

}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
}
}
}
}
shuifengcun 2010-02-23
  • 打赏
  • 举报
回复
good study...............
xingyuebuyu 2010-02-23
  • 打赏
  • 举报
回复
现在运行没有错误的程序贴出来大家看看啊
tonnycao 2010-02-23
  • 打赏
  • 举报
回复
引用 54 楼 soaringbird 的回复:
senReadDSPData的C++定义?

就是没有他的定义啊,只是看c++程序中对readdata.dll的使用列子来试试c#下开发的!现在程序没有运行错误,但是没有取得数据。
miaochongda 2010-02-23
  • 打赏
  • 举报
回复
对了,我是动态调用的!你的是静态调用的!
miaochongda 2010-02-23
  • 打赏
  • 举报
回复
我的调用过程如下,不知道对你是否有用!
C++中的函数原型如下:
BOOL GetDisData(USHORT* disData, int* frameLen, int frameNeed, int aziAccNum, int radAccNum)
C#中委托如下:
public delegate bool GetDisData(IntPtr disData, IntPtr frameLen, int frameNeed, int aziAccNum, int radAccNum);
C#中调用如下:
private GetDisData gdd;
private IntPtr dataPtr;
private IntPtr dataLen;

//函数调用
gdd(dataPtr, dataLen, 1, 16, 1);

//读数据
Marshal.ReadInt32(dataLen)
tonnycao 2010-02-23
  • 打赏
  • 举报
回复
没有原型,只有c++调用示例,我原来一个项目也用过c# 调用dll,只有一个结构体,结构体中有byte数组,使用的时候都没有问题。这个结构比较复杂。
加载更多回复(56)

110,546

社区成员

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

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

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