【发布时间】:2012-03-29 22:02:18
【问题描述】:
我正在尝试使用 VB.NET 调用外部 C++ 函数(C# 中的答案很好,我可以转换回来),它返回设备名称列表。这以指向以空结尾的 char 数组的空结尾数组的指针的形式出现(如果我误解了我正在处理的内容,请纠正我)并带有函数签名:
long GetNames(char*** names)
我发现的大多数类似问题的答案都涉及以下内容:
long GetNames(char** names, int length)
从我读到的内容看来,我需要给它一个 IntPtr,但我不确定应该如何初始化它,而且在我的情况下,我不知道数组的长度。目前,在VB模块中,我有:
<DllImport("MyExternal.dll", CallingConvention:=CallingConvention.Cdecl)> _
Function GetNames(ByRef names as IntPtr) As UInteger
End Function
我尝试通过传递初始化为 IntPtr.Zero 的 IntPtr 或使用 Marshall.AllocHGlobal 来调用该函数,但我总是得到一个 AccessViolationException。
任何关于我应该如何调用此函数以及如何将返回值放入托管字符串数组的想法将不胜感激。
编辑:我在本机 C 中找到了一个示例函数调用,如下所示:
char **tmplist;
GetNames(&tmplist)
【问题讨论】:
-
您至少需要分配
char*的数组。您可能还需要分配构成此数组的char*项。GetNames的文档对此事有何评论。 -
这是函数的描述:“列出可用设备。此函数返回一个指向以 NULL 结尾的设备名称列表的指针。稍后应使用 FLIFreeList() 释放该指针。每个设备名称在返回的列表包括 FLIOpen() 所需的文件名,一个分隔分号,后跟型号名称或用户分配的设备名称。”这就是它为
names参数提供的内容:“指向设备名称列表将被放置的位置的指针。” -
您的
GetNames在这种情况下看起来不错。你在什么时候得到AV?当您调用GetNames时,或者当您使用它返回的内容时?你知道返回值是什么意思吗?是错误代码吗? -
调用
GetNames时抛出AV。返回值确实表示错误代码(0 = 成功,非 0 = 失败 - 没有比这更具体的了),但无论如何执行不会继续超出调用,我无法处理try...catch的异常。 -
你有C语言的示例调用代码吗?这让我很困惑。您无需担心初始化名称,因为它是一个输出值。