C#Interop:out params也可以为null

时间:2009-10-01 22:14:04

标签: c# interop

考虑以下DllImport:

[DllImport("lulz.so")]
public static extern int DoSomething(IntPtr SomeParam);

这实际上引用了这样的C风格函数:

int DoSomething(void* SomeParam); 

考虑SomeParam是一个“out”参数,但也可以是NULL。如果param为NULL,则C函数的行为会有所不同。所以我可能想要:

[DllImport("lulz.so")]
public static extern int DoSomething(out IntPtr SomeParam);

但是,如果我在导入中将其设为out参数,则无法将其传递为NULL,即我无法执行此操作:

int retVal = DoSomething(IntPtr.Zero)

我有什么选择?

5 个答案:

答案 0 :(得分:8)

如果您尝试传递值,则out不是正确的关键字;将其更改为ref。您仍然需要显式传递变量,但它可以是null引用。

例如......

[DllImport("lulz.so")]
public static extern int DoSomething(ref IntPtr SomeParam);

然后你可以这样称呼它:

IntPtr retVal = IntPtr.Zero;

DoSomething(ref retVal);

然而

什么告诉您需要outref?将IntPtr作为outref传递实际上类似于传递双指针。将参数作为IntPtr传递似乎更合适。

典型的过程是在托管代码中分配必要的内存,并传递表示已分配内存的IntPtr,或IntPtr.Zero表示空指针。您无需将IntPtr作为outref传递,以便将数据发送回.NET;如果您正在调用的函数实际上更改指针的地址,则只需要这样做。

答案 1 :(得分:0)

我不明白问题是什么......

这运行:

private void button2_Click(object sender, EventArgs e) {
    object bar;
    Method(out bar);

    bar = IntPtr.Zero;
    Method(out bar);
}

private void Method(out object foo) {
    foo = null;
}

答案 2 :(得分:0)

传递NULL的意图是什么?是否打算像往常一样调用方法,而只是不设置输出参数?

在这种情况下,我想我只是用C#中的重载包装extern方法。那个重载(没有out参数)就像这样:

public void DoSomething()
{
    IntPtr dummy;
    DoSomething(out dummy);
}

答案 3 :(得分:0)

我遇到过这一次。我最终自己编组指针(请参阅Marshal Members以获取库函数)。

答案 4 :(得分:0)

就个人而言,我会导入此函数两次,第一次使用'out'参数,第二次使用'in'。

[DllImport("lulz.so")]
public static extern int DoSomething(out IntPtr SomeParam);

// call as DoSomethingWithNull(IntPtr.Zero)
[DllImport("lulz.so", EntryPoint="DoSomething")]
public static extern int DoSomethingWithNull(IntPtr SomeParam);

这将解决您的问题并使代码更具可读性。