在C#中使用struct调用C函数 - 我做错了什么?

时间:2013-09-20 12:59:55

标签: c# c struct pinvoke

我认为这个相当直接,但仍然试图了解所有这些并遇到一些问题。

我不太了解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,但它没有传递卡号,然后设置一条消息说卡号没有通过。

非常感谢任何帮助。 谢谢!

3 个答案:

答案 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导入中使用CallingConventionCharSet,并在参数之前使用[In, Out]属性。像这样:

[DllImport("card.dll")]
public static extern int GetCardInfo([In, Out] CardInfo cardInfo);