考虑以下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)
我有什么选择?
答案 0 :(得分:8)
如果您尝试传递值,则out
不是正确的关键字;将其更改为ref
。您仍然需要显式传递变量,但它可以是null
引用。
例如......
[DllImport("lulz.so")]
public static extern int DoSomething(ref IntPtr SomeParam);
然后你可以这样称呼它:
IntPtr retVal = IntPtr.Zero;
DoSomething(ref retVal);
什么告诉您需要out
或ref
?将IntPtr
作为out
或ref
传递实际上类似于传递双指针。将参数作为IntPtr
传递似乎更合适。
典型的过程是在托管代码中分配必要的内存,并传递表示已分配内存的IntPtr
,或IntPtr.Zero
表示空指针。您无需将IntPtr
作为out
或ref
传递,以便将数据发送回.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);
这将解决您的问题并使代码更具可读性。