gpt4 book ai didi

c# - 在 C# COM 中处理 NULL 指针输出参数

转载 作者:太空狗 更新时间:2023-10-30 01:25:35 26 4
gpt4 key购买 nike

我正在使用具有以下函数定义的 COM 插件接口(interface):

HRESULT foo ( [out, ref] VARIANT* a, [out, ref] VARIANT* b );

当使用 tlbimp(来自 codeplex 的 tlbimp2.exe)时,.NET 库具有以下接口(interface)函数:

int foo ( out object a, out object b );

问题是调用应用程序将进行函数调用:

VARIANT a;
::InitVariant( &a );

plugin->foo( &a, NULL );

我在 C# 中实现了函数:

int foo ( out object a, out object b )
{
a = 1;
b = 2;

return 0; // S_OK
}

当一切都说完了之后,应用程序实际上得到了一个 E_POINTER 返回值,而不是 S_OK。我认为这是因为 NULL 传递了 out 参数。

有没有办法在 C# 实现中检查地址指针是否为 NULL?

注意:out 参数未初始化,因此您根本无法使用这些参数。

我尝试将接口(interface)实现为 [in, out, ref] 以强制 C# 使用(ref object a, ref object b),但这也不起作用。

更新

如果我们将函数声明为 [out,ref],Hans 绝对正确,我们应该使用 NULL ptr 调用该函数。

erurainon 也是正确的,我们可以只使用 IntPtr 来获取 Variant*。

所以这里是它是如何修复的:

int foo ([MarshalAs(UnmanagedType.Struct)]out object a, [MarshalAs(UnmanagedType.Struct)]out object b);

成为

int foo ([MarshalAs(UnmanagedType.Struct)]out object a, IntPtr b );

现在我们可以测试 NULL 情况:

if ( b == IntPtr.Zero )

然而,由于我们正在处理 Variant,您不能像这样将值复制到 IntPtr:

Marshal.StructureToPtr( myValue, b, false );

接着this post ,你需要做一个结构类:

[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PropVariant
{
[FieldOffset(0)]
public VarEnum variantType;
[FieldOffset(8)]
public IntPtr pointerValue;
[FieldOffset(8)]
public byte byteValue;
[FieldOffset(8)]
public long longValue;
[FieldOffset(8)]
public double dateValue;
[FieldOffset(8)]
public short boolValue;
}

最终的函数如下所示:

int foo( out object a, IntPtr b )
{
a = 100;

if ( b != IntPtr.Zero )
{
var time = new PropVariant();
time.dateTime = DateTime.Now.ToOADate();
time.variantType = VarEnum.VT_DATE;

Marshal.StructureToPtr( time, b, false );
}

return 0; // S_OK
}

希望这对以后的其他人有帮助

最佳答案

来自MIDL docs :

The [ref] attribute identifies a reference pointer. It is used simply to represent a level of indirection
....
A reference pointer has the following characteristics:
- Always points to valid storage; never has the value NULL. A reference pointer can always be dereferenced.

代码无效,它传递了 NULL。直接违反 [ref] 契约(Contract)。到此为止,您将修复 MIDL 或 native 代码。

关于c# - 在 C# COM 中处理 NULL 指针输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6632112/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com