我认为这个相当直接,但仍然试图了解所有这些并遇到一些问题。
我不太了解C函数b / c我得到了有限的信息。
这是C中的函数调用:
int GetCard(CardInfo card);
这是请求结构:
typedef struct _tCardInfo
{
char CardNumber[80];
char isExist;
} TCardInfo, *pTCardInfo;
我想传递卡号以查看它是否存在。
所以在C#中我做了以下事情:
public struct CardInfo
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string cardNumber;
public byte isExist;
}
[DllImport("card.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern int GetCardInfo(ref CardInfo cardInfo);
然后在c#方法中:
CardInfo cardInfo = new CardInfo();
cardInfo.cardNumber = "1234567890";
int success = GetCardInfo (ref cardInfo);
我正在调用的DLL的好处是它生成一个日志文件。 当我执行调用时,日志告诉我我正在点击DLL,但它没有传递卡号,然后设置一条消息说卡号没有通过。
非常感谢任何帮助。 谢谢!
答案 0 :(得分:1)
问题是您正在请求TChar编组,但DLL需要8个字节的字符。将C结构更改为wchar_t。
此外,使用Visual Studio在DLL中设置断点,并在数据进入时实际检查数据! Visual Studio可以跨.NET /本地边界进行调试,这非常酷!
答案 1 :(得分:0)
尝试为struct
添加属性StructLayout[StructLayout(LayoutKind.Sequential)]
public struct CardInfo
{
...
答案 2 :(得分:0)
尝试像这样创建.Net结构:
[StructLayout(LayoutKind.Sequential)]
public struct CardInfo
{
[MarshalAs(UnmanagedType.AnsiBStr, SizeConst = 80)]
public string cardNumber;
[MarshalAs(UnmanagedType.I1)]
public sbyte isExist;
}
对于函数声明:尽量不要在DLL导入中使用CallingConvention
和CharSet
,并在参数之前使用[In, Out]
属性。像这样:
[DllImport("card.dll")]
public static extern int GetCardInfo([In, Out] CardInfo cardInfo);