2012-11-27 130 views
0

首先,我会说我已经搜索了高和低的答案,当我发现了一些对我来说都是胡言乱语,而不是一个C++程序员。编程对我来说只是一种爱好。SafeArrayTypeMismatchException尝试使用非托管C++ DLL

我在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); 

我真的不知道很多关于三分球,但我猜,我会在C#中使用“参考”。

这里是他的自述功能:

CalcDDtable

CalcDDtable计算的最初52卡双虚拟值,所有的20个王牌/庄家手的组合。

在调用CalcDDtable之前,必须声明一个“ddTableResults”类型的结构。 CalcDDtable返回一个状态整数,“无故障”表示DLL在“ddTableResults”类型结构中提供双重虚拟分数。 状态码:
1 =无故障, 其他状态代码为错误,代码等于SolveBoard状态代码。

结构“ddTableDeal”定义要分析的发卡。结构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

您需要描述结构的布局。

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

似乎有不是一个方式来表达阵列是2维的,所以我刚给出的阵列,就好像它是一维的全尺寸。 (在C中,多维数组在内存中连续布局。)请注意,元素类型是int,而不是short - 它是32位。你也应该为其他结构做同样的事情。

(未经测试的代码)

+0

谢谢ymett,一旦我将char数组更改为80的固定长度,这很奏效。 – cjk84