尝试使用非托管C ++ DLL时出现SafeArrayTypeMismatchException

时间:2012-11-27 12:12:45

标签: c# c++

首先,我会说我已经搜索到了这个问题的答案,当我找到了一些对我来说都是胡言乱语的人,而不是C ++程序员。编程只是我的一个爱好。

我在C#winforms项目中使用Visual Studio 2010 Ultimate,以防万一!

问题是我正在尝试使用非托管DLL中的函数(Bo Haglund' Double Dummy Solver)。他的自述文件不太有用,而且关于如何使用他的DLL的文章很少(即没有)。

我有我希望使用的DLL中的函数原型。

extern "C" __declspec(dllimport) int __stdcall CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep);

我对指针并不是很了解,但我猜我会使用" ref"在C#。

以下是他关于该功能的自述文件:

  

CalcDDtable

     

CalcDDtable计算所有20个特朗普套装/声明者手牌组合的初始52张牌的双重虚拟值。

     

在调用CalcDDtable之前,可以使用类型" ddTableResults"必须申报。   CalcDDtable返回一个状态整数,"没有错误"表示DLL在" ddTableResults"中提供双虚拟分数。类型结构。   状态代码:
     1 =没有错,      其他状态代码是错误,代码等于SolveBoard状态代码。

     

结构“ddTableDeal”定义要分析的处理卡。   struct ddTableDeal {     unsigned int cards [4] [4]; / *第一个索引是手,第二个索引适合,与SolveBoard的deal.remainCards编码相同。 * /   };

struct ddTableResults { /* For each combination trump suit / declarer hand, the DLL provides the double dummy score. */
  int resTable[5][4];   /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */
};
  

CalcDDtablePBN

     

在CalcDDtablePBN中,交易信息中的剩余卡片以PBN文本格式给出,请参阅上面针对SolveBoardPBN的说明。否则,CalcDDtablePBN与CalcDDtable相同。

struct ddTableDealPBN {
  char cards[80];
};

我导入了如下函数:

[DllImport("dds.dll")]
public static extern int CalcDDtablePBN(DDTableDealPBNStruct tableDealPBN, ref DDTableResultsStruct tablep);

以下是我的结构:

public struct DDTableDealPBNStruct
{
    public char[] cards;

    public DDTableDealPBNStruct(char[] pbnCards)
    {
        cards = pbnCards;
    }
}

public struct DDTableResultsStruct
{
    public short[,] resTable; /* 1st index is trump (0=Spades, 1=Hearts, 2=Diamonds, 3=Clubs, 4=No Trump 2nd index is declarer hand, 0=North, 1=East, 2=South, 3=West */
}

这就是我调用函数的方式:

const string _dealPBN = "N:QJT..AJ76.AKJ765 AK64.AKJ7654..98 32.T932.KQ32.T43 9875.Q8.T9854.Q2";
DDTableDealPBNStruct tdPBN = new DDTableDealPBNStruct(_dealPBN.ToCharArray());
DDTableResultsStruct results = new DDTableResultsStruct();
results.resTable = new short[5, 4];
CalcDDtablePBN(tdPBN, ref results);

当我运行程序时,这是我收到的错误消息:

  

SafeArrayTypeMismatchException未处理。   指定的数组不是预期的类型。

它没有提到哪个数组是坏的,但我猜测它是短[5,4]数组。我尝试了不同的[MarshalAs(UnmanagedType.blah)]选项无济于事。谁能告诉我我做错了什么?老实说,我很难过。

我还尝试了几种不同的数组类型,int,uint,short,Int16等,再次无济于事。除非我错了,它是抱怨的char []数组?

提前谢谢。

1 个答案:

答案 0 :(得分:1)

您需要描述结构的布局。

[StructLayout(LayoutKind.Sequential)]
public struct DDTableResultsStruct
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public int[] resTable;
}

似乎没有办法说数组是二维的,所以我只是给出了数组的完整大小,就好像它是1维的一样。 (在C中,多维数组在内存中连续排列。)请注意,元素类型为int,而不是short - 它是32位。你也应该为其他结构做同样的事情。

(未经测试的代码。)