我试图从 C# 调用一个函数到一个用 Borland C++ 编写的 .DLL,其签名是:
extern "C" __declspec(dllexport) ls50errortype __stdcall Ls50P2Open(ls50p2apiconfiginfostruct &configinfo);
C#中对应的调用:
[DllImport("C:\\Lumistar\\LDPS_8x\\Ls50P2_Dll.dll", EntryPoint = "Ls50P2Open", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall, CharSet = CharSet.Ansi, SetLastError = true)]
public static extern void Ls50P2Open(ref ls50p2apiconfiginfostruct configinfo);
感兴趣的结构(ls50p2apiconfiginfostruct)由嵌套结构和枚举组成(从 C++ 标头复制):
typedef enum
{
MFMODEL_LS50P1,
MFMODEL_4422PCI,
MFMODEL_LS50P2,
MFMODEL_LS70P2,
MFMODEL_LS5070,
MFMODEL_LAST
}ecardmodel;
typedef enum
{
CHANNELDEVICE_NONE,
CHANNELDEVICE_50,
CHANNELDEVICE_70,
CHANNELDEVICE_LAST
}ls50p2channeldevicetype;
typedef enum
{
LS50V2DCARD_NONE,
LS50V2DCARD_40V1_10,
LS50V2DCARD_40V1_20,
LS50V2DCARD_40V2_10,
LS50V2DCARD_40V2_20,
LS50V2DCARD_38,
LS50V2DCARD_LAST
}ls50p2daughtercardtype;
typedef struct
{
bool HasDaughterCard;
ls50p2daughtercardtype DCardType;
bool SpecialStatusCapable;
int MaxBitsyncInputs;
bool HasBitsyncConfidenceLevel;
bool HasBitsync2ndCh;
bool SpecialStatusCapable2ndCh;
bool HasBitsyncConfidenceLevel2ndCh;
ls50p2daughtercardtype DCardType2ndCh;
int MaxBitsyncInputs2ndCh;
}ls50p2daughtercardinfostruct;
typedef struct
{
ecardmodel DeviceModel;
ls50p2channeldevicetype ChannelDataTypeAry[2];
ls50p2daughtercardinfostruct DaughterCardInfo;
bool HasExtendedBertPatterns;
int FirmwareVersionAry[2];
int NumPremodFiltersAry[2];
double Ls50SimPreModFilterKhzAry[2][LS50V2_MAX50SIMPREMODFILTERS];
double Ls50SimMinFmDeviationKhzAry[2];
double Ls50SimMaxFmDeviationKhzAry[2];
}ls50p2cardconfigstruct;
typedef struct
{
unsigned char *DataBuf;
HANDLE hNewDataRdy;
DWORD MaxBufLength;
DWORD CurrentBufLength;
int NumHeaderBytes;
}ls50p2carddatastruct;
typedef struct
{
ls50p2cardconfigstruct CardConfigInfo[MAXMFCARDS];
int Ls50P2CardCount;
ls50p2carddatastruct DataInfo[MAXMFCARDS][2];
}ls50p2apiconfiginfostruct;
这是 C# 中的相应结构:
public enum ecardmodel
{
MFMODEL_LS50P1,
MFMODEL_4422PCI,
MFMODEL_LS50P2,
MFMODEL_LS70P2,
MFMODEL_LS5070,
MFMODEL_LAST
}
public enum ls50p2channeldevicetype
{
CHANNELDEVICE_NONE,
CHANNELDEVICE_50,
CHANNELDEVICE_70,
CHANNELDEVICE_LAST
};
public enum ls50p2daughtercardtype
{
LS50V2DCARD_NONE,
LS50V2DCARD_40V1_10,
LS50V2DCARD_40V1_20,
LS50V2DCARD_40V2_10,
LS50V2DCARD_40V2_20,
LS50V2DCARD_38,
LS50V2DCARD_LAST
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2daughtercardinfostruct
{
public bool HasDaughterCard;
public ls50p2daughtercardtype DCardType;
public bool SpecialStatusCapable;
public int MaxBitsyncInputs;
public bool HasBitsyncConfidenceLevel;
public bool HasBitsync2ndCh;
public bool SpecialStatusCapable2ndCh;
public bool HasBitsyncConfidenceLevel2ndCh;
public ls50p2daughtercardtype DCardType2ndCh;
public int MaxBitsyncInputs2ndCh;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2cardconfigstruct
{
public ecardmodel DeviceModel;
public ls50p2daughtercardtype[] ChannelDataTypeAry;
public ls50p2daughtercardinfostruct DaughterCardInfo;
public bool HasExtendedBertPatterns;
public int[] FirmwareVersionAry;
public int[] NumPremodFiltersAry;
public double[] Ls50SimPreModFilterKhzAry;
public double[] Ls50SimMinFmDeviationKhzAry;
public double[] Ls50SimMaxFmDeviationKhzAry;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2carddatastruct
{
public StringBuilder DataBuf;
public IntPtr hNewDataRdy;
public uint MaxBufLength;
public uint CurrentBufLength;
public int NumHeaderBytes;
}
[StructLayout(LayoutKind.Sequential)]
public struct ls50p2apiconfiginfostruct
{
public ls50p2cardconfigstruct[] CardConfigInfo;
public int Ls50P2CardCount;
public ls50p2carddatastruct[,] DataInfo;
}
这是我用来调用该函数的 C# 代码:
ls50p2apiconfiginfostruct lscfg = new ls50p2apiconfiginfostruct();
lscfg.CardConfigInfo = new ls50p2cardconfigstruct[8];
for (int i = 0; i < 8; i++)
{
lscfg.CardConfigInfo[i].ChannelDataTypeAry = new ls50p2daughtercardtype[2];
}
lscfg.DataInfo = new ls50p2carddatastruct[8, 2];
Ls50P2Open(ref lscfg);
我曾尝试在 C# 中制作此结构,但没有取得太大成功(枚举、二维数组、固定大小缓冲区的问题)。在 C# 中创建此结构的正确方法是什么?这需要在不安全的环境中进行吗?
现在由于某种原因,我在运行代码时收到以下错误:
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in Library.dll Additional information: Old format or invalid type library. (Exception from HRESULT: 0x80028019 (TYPE_E_UNSUPFORMAT))