C#调用dll函数在x64平台下调试闪退

Lena- 2019-06-21 04:17:26
[DllImport("ACTS1011_64.DLL")]
public static extern Boolean ACTS1011_InitDeviceAD(IntPtr hDevice,ref PCle8914_PARA_AD pADPara);


调用了外部dll函数,里面参数是一个结构体,我也定义了相应的结构体,在x86平台下调试可以,但是x64下调时就会闪退且没有原因

VC的头文件是这样的
typedef struct _ACTS1011_PARA_AD     
{
LONG bChannelArray[8]; // 采样通道选择阵列,分别控制8个通道,=TRUE表示该通道采样,否则不采样
LONG InputRange[8]; // 模拟量输入量程选择
LONG CouplingType[8]; // 耦合类型(直流耦合, 交流耦合)
LONG InputImped[8]; // 输入阻抗控制阵列,分别控制8个通道(暂不支持)
LONG FreqDivision; // 分频数[1, 2147483647],外时钟:采样频率=外部时钟频率/分频数;其它时钟:采样频率=基准频率/分频数;
LONG SampleMode; // 采样模式(有限采样,连续采样)
ULONG M_Length; // M段长度(字),延时触发M表示延时点数范围[0, 4294967295],有限点采样延时触发有效
ULONG N_Length; // N段长度(字),有限点采样有效
// 后触发M必须为0,N为有效读取点数;硬件延时触发N为有效读取点数;
// N*使能通道数*触发次数 必须为2048的整数倍
LONG PFISel; // PFI功能选择, 详见下面常量定义(仅板卡8582 8584支持)
LONG TriggerMode; // 触发模式选择
LONG TriggerSource; // 触发源选择
LONG TriggerDir; // 触发方向选择(下降沿/上升沿/上下边沿均触发)
LONG TrigLevelVolt; // 触发电平(量程按模拟输入量程)
LONG TrigWindow; // 触发灵敏窗单位nS,步进为本卡最高采样率的采样周期;例如最高80M,步进即为12.5nS
ULONG TrigCount; // 触发次数设置,默认为1,为0时表示无限触发,此功能仅在有限采样下有效
LONG ReferenceClock; // 参考时钟选择
LONG TimeBaseClock; // 采样时基选择
LONG bMasterEn; // 主设备使能
// =0:从设备,接收主设备发送的同步触发信号
// =1:主设备,为从设备发送自身的触发信号
// 注:在多模块同步系统中,只能设定其中一个设备为主设备,其余需设定为从设备,如果系统中只有一个设备或者有多个设备但是不要求同步,需将所有设备设定为从设备
LONG SyncTrigSignal; // 同步触发源
LONG bClkOutEn; // 时钟是否输出,TRUE输出
LONG ClkOutSel; // 时钟输出选择
LONG bTrigOutEn; // 触发是否输出,TRUE输出
LONG TrigOutPolarity; // 触发输出极性
LONG TrigOutWidth; // 触发脉冲输出宽度单位nS,[50, 50000]步进50nS
BOOL bSaveFile; // 是否自动存盘 =TRUE:存盘
TCHAR chFileName[256]; // 存盘路径及名称,例:L"F:\\1.pci"
} ACTS1011_PARA_AD, *PACTS1011_PARA_AD;


c#里是这样的
        public struct PCle8914_PARA_AD
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public long[] bChannelArray; // 采样通道选择阵列,分别控制个通道,=TRUE 表示该通道采样,否则不采样(只支持种通道配置:0 01 0123)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public long[] InputRange; // 模拟量输入量程选择
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public long[] CouplingType; // 耦合类型(直流耦合, 交流耦合)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public long[] InputImped; // 输入阻抗控制阵列,分别控制8个通道(暂不支持)
public long FreqDivision; // 分频数[1, 2147483647],外时钟:采样频率=外部时钟频率/分频数;其它时钟:采样频率=基准频率/分频数;
public long SampleMode; // 采样模式(有限采样,连续采样)
public long M_Length; // M 段长度(字),延时触发 M 表示延时点数范围[0, 2147483647]
public long N_Length; // N 段长度(字)
// 中间触发 M N 有效读取点数;后触发 M 必须为,N 有效读取点数;预触发 M 必须为,N 有效读取点数; 硬件延时触发 N 有效读取点数;
// 各种触发下有效读取点数相加范围[16/使能通道数, 内存大小(字节)/2/使能通道数], 有效读取点数相加必须为(16/使能通道数)的整数倍
public long PFISel; // PFI功能选择, 详见下面常量定义(仅板卡8582 8584支持)
public long TriggerMode; // 触发模式选择
public long TriggerSource; // 触发源选择
public long TriggerDir; // 触发方向选择(正向/负向触发)
public long TrigLevelVolt; // 触发电平(量程按模拟输入量程)
public long TrigWindow; // 触发灵敏窗单位 nS,步进 5nS

public ulong TrigCount; // 触发次数设置,默认为次,此功能仅在后触发和硬件延时触发模式下有效,触发次数* 有效读取点数*使能通道数*2<=内存大小(字节)
public long ReferenceClock; // 参考时钟选择
public long TimeBaseClock; // 采样时基选择
public long bMasterEn; // 主设备使能
// =0: 从设备,接收主设备发送的同步触发信号
// =1: 主设备,为从设备发送自身的触发信号
// 注: 在多模块同步系统中,只能设定其中一个设备为主设备,其余需设定为从设备,如果系统中只有一个设备或者有多个设备但是不要求同步,需将所有设备设定为从设备
public long SyncTrigSignal; // 同步触发源
public long bClkOutEn; // 时钟是否输出,TRUE 输出
public long ClkOutSel; // 时钟输出选择
public long bTrigOutEn; // 触发是否输出,TRUE 输出16
public long TrigOutPolarity; // 触发输出极性
public long TrigOutWidth; // 触发脉冲输出宽度单位 nS,[50, 50000]步进 nS
public bool bSaveFile; // 是否自动存盘 =TRUE:存盘
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public char [] chFileName; // 存盘路径及名称,例如:"F:\\1.pci"
}
...全文
1287 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yzsw521 2020-05-02
  • 打赏
  • 举报
回复
exe和dll的架构必须都同时为x86或者x64。 或者2个都同时编译为 any cpu。
牧童吃五谷 2019-07-10
  • 打赏
  • 举报
回复
x86运行正常,那么可以确定你的dll是32位的程序,那么也一定要让你的exe程序也是32位程序才能够调用的,而c#程序一般可以自动选择,所以建议强制把c#程序改为32位编译运行试一试
stherix 2019-06-22
  • 打赏
  • 举报
回复
exe和dll的架构必须都同时为x86或者x64 而且c#里long和c++LONG长度不一定一样 c#里最好写Int64,Int32这种
OrdinaryCoder 2019-06-21
  • 打赏
  • 举报
回复
dll是你们自己写的吗 改下接口改成char好一点 如果不是 就用CLI或者C++包装一下
OrdinaryCoder 2019-06-21
  • 打赏
  • 举报
回复
好像是tchar的原因 这个类型的变量会变
Lena- 2019-06-21
  • 打赏
  • 举报
回复
引用 2 楼 OrdinaryCoder 的回复:
在C#结构体上面加上 [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]这个

重点是x86平台下调用32位dll是可以的 但是x64位下调用64位dll就不行
Lena- 2019-06-21
  • 打赏
  • 举报
回复
引用 2 楼 OrdinaryCoder 的回复:
在C#结构体上面加上 [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]这个

改为int 前面加上了还是闪退
OrdinaryCoder 2019-06-21
  • 打赏
  • 举报
回复
在C#结构体上面加上 [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]这个
OrdinaryCoder 2019-06-21
  • 打赏
  • 举报
回复
1.C++的long对应C#的int long long对应C#long
2.TCHAR根据字符编码不同 位数也不一样 有可能是一个字节 有可能是2或者4个字节

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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