1

我正在使用第三方 COM 组件(即没有它的代码)。有问题的方法具有以下概述:

HRESULT GetTableInfo(  
[in] BSTR bstrTableName, 
[in,out] SAFEARRAY(BSTR) bstrColumnTitles, 
[in,out] SAFEARRAY(long) lColumnPos );

我试图将 ref 传递给固定大小的数组 ((Array)string[6]) 和 List.ToArray(),但它一直在我身上崩溃。例如

Array arr1 = (Array) new string[500];
Array arr2 = (Array) new int[500];
table.GetTableInfo(filename, ref arr1, ref arr2);

更具体地说:我已经尝试了任何大小的值(正确的值应该是 44)。对 List<> 的容量进行了同样的尝试,但这也无济于事。我也尝试了不同的类型,但它不接受除 int 之外的任何类型。

我不知道为什么它总是因为该 COM 组件的一般错误而崩溃(基本上表明出了点问题,但没有说到底是什么),因为我可以确认以下 VB 代码有效:

Dim TitleList() As String
Dim PositionList() As Long 
Call objTable.GetTableInfo(txTableFile.Text, TitleList, PositionList)

有谁知道为什么会发生这种情况?或者,任何人都可以为我提供将该 VB 代码移植到 C# 的端口吗?我曾尝试用谷歌搜索教程,但他们所说的只是“只允许使用固定大小的数组”。我想知道那个代码是如何工作的,因为没有指定大小。

感恩节

4

1 回答 1

1

你读过Default Marshaling for Arrays吗?据我所知,只要您使用MarshalAsPInvoke 声明中的属性来指示该数组应编组为安全数组,这应该“正常工作”。

据我所知,正确的 PInvoke 声明应该是这样的

public static string extern GetTableInfo(
    string tableName,
    [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_BSTR)]
    ref string[] columnTitles,
    [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I8)]
    ref long[] columnPos
);

你能告诉我们你的 PInvoke 声明是什么样的吗?

于 2011-11-21T16:51:46.527 回答