尝试使用非托管C++DLL时出现SafeArrayTypeMismatchException
SafeArrayTypeMismatchException while trying to use unmanaged C++ DLL
首先,我要说的是,我已经到处寻找答案,当我发现一些东西时,我觉得这都是胡言乱语,而不是C++程序员。编程对我来说只是一种爱好。
我正在C#winforms项目中使用Visual Studio 2010 Ultimate,以防有帮助!
问题是我正在尝试使用非托管DLL中的函数(Bo Haglund的双伪解算器)。他的自述没有什么帮助,而且关于如何使用他的DLL的文章少得惊人。
我在DLL中有我想要使用的函数的原型。
extern "C" __declspec(dllimport) int __stdcall CalcDDtablePBN(struct ddTableDealPBN tableDealPBN, struct ddTableResults * tablep);
我真的不太了解指针,但我猜我会在C#中使用"ref"。
以下是他关于函数的自述:
可计算的
CalcDDtable计算所有20个王牌/解密手牌组合的初始52张牌的双伪值。
在调用CalcDDtable之前,必须声明"ddTableResults"类型的结构。CalcDDtable返回一个状态整数,"无错误"表示DLL在"ddTableResults"类型结构中提供双倍的伪分数。状态代码:
1=无故障,其他状态代码是错误,其代码等于SolveBoard状态代码。结构"ddTableDeal"定义了要分析的已发牌。结构ddTableDeal{无符号int卡[4][4];/*第一个索引是手,第二个索引是西装,与deal.mainCards for SolveBoard的编码相同*/};
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 */
};
CalcDDablePBN
在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[]数组?
提前谢谢。
您需要描述结构的布局。
[StructLayout(LayoutKind.Sequential)]
public struct DDTableResultsStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public int[] resTable;
}
似乎没有办法说数组是二维的,所以我只给出了数组的完整大小,就好像它是一维的一样。(在C中,多维数组在内存中连续排列。)请注意,元素类型是int
,而不是short
——它是32位的。您也应该对其他结构执行同样的操作。
(未测试代码。)
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL