我创建了一个在C++中存储字节型VARIANT的SAFEARRAY。
当这个结构体被传递到C#时,出现了奇怪的问题。
如果我在C#中将该结构体的内容打印到WinForms的ListBox中,例如:
我得到了一些与原始数字似乎无关的数字。此外,每次我为新测试运行C#客户端时,我都会得到不同的数字集合。
请注意,如果我使用Visual Studio调试器检查该
请注意,如果我在 C++ 中创建一个直接存储 BYTE 的 SAFEARRAY(而不是 SAFEARRAY(VARIANT)),则可以立即在 C# 中获得正确的值,无需中间的 CopyTo 操作。
当这个结构体被传递到C#时,出现了奇怪的问题。
如果我在C#中将该结构体的内容打印到WinForms的ListBox中,例如:
byte data[]
TestSafeArray(out data);
lstOutput.Items.Clear();
foreach (byte x in data)
{
lstOutput.Items.Add(x); // Strange numbers
}
我得到了一些与原始数字似乎无关的数字。此外,每次我为新测试运行C#客户端时,我都会得到不同的数字集合。
请注意,如果我使用Visual Studio调试器检查该
data
数组的内容,我将获得正确的数字,如下面的截图所示:
然而,如果我将编组的数据数组CopyTo
到一个新数组中,我会得到正确的数字: byte[] data;
TestSafeArray(out data);
// Copy to a new byte array
byte[] byteData = new byte[data.Length];
data.CopyTo(byteData, 0);
lstOutput.Items.Clear();
foreach (byte x in byteData)
{
lstOutput.Items.Add(x); // ** WORKS! **
}
这是我用来构建 SAFEARRAY
的 C++ 代码(此函数是从本地 DLL 导出的):
extern "C" HRESULT __stdcall TestSafeArray(/* [out] */ SAFEARRAY** ppsa)
{
HRESULT hr = S_OK;
try
{
const std::vector<BYTE> v{ 11, 22, 33, 44 };
const int count = static_cast<int>(v.size());
CComSafeArray<VARIANT> sa(count);
for (int i = 0; i < count; i++)
{
CComVariant var(v[i]);
hr = sa.SetAt(i, var);
if (FAILED(hr))
{
return hr;
}
}
*ppsa = sa.Detach();
}
catch (const CAtlException& e)
{
hr = e;
}
return hr;
}
这是我使用的C# P/Invoke:
[DllImport("NativeDll.dll", PreserveSig = false)]
private static extern void TestSafeArray(
[Out, MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_VARIANT)]
out byte[] result);
请注意,如果我在 C++ 中创建一个直接存储 BYTE 的 SAFEARRAY(而不是 SAFEARRAY(VARIANT)),则可以立即在 C# 中获得正确的值,无需中间的 CopyTo 操作。