Reputation: 800
Consider the following DllImport:
[DllImport("lulz.so")]
public static extern int DoSomething(IntPtr SomeParam);
This is actually referencing a C style function like this:
int DoSomething(void* SomeParam);
Consider that SomeParam is an "out" param, but can also be NULL. The C function behaves differently if the param is NULL. So I would probably want:
[DllImport("lulz.so")]
public static extern int DoSomething(out IntPtr SomeParam);
But, if I make it an out param in my import, I cannot pass it NULL, i.e. I can't do this:
int retVal = DoSomething(IntPtr.Zero)
What are my options here?
Upvotes: 2
Views: 4393
Reputation: 7879
Personally, I'd import this function twice, first time with 'out' parameter, second with '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);
This will solve your problem and will make code more readable.
Upvotes: 0
Reputation: 185663
If you're trying to pass a value, then out
is not the right keyword; change it to ref
. You'll still need to explicitly pass a variable, but it can be a null
reference.
For example...
[DllImport("lulz.so")]
public static extern int DoSomething(ref IntPtr SomeParam);
You can then call it like this:
IntPtr retVal = IntPtr.Zero;
DoSomething(ref retVal);
What is telling you that it needs to be either out
or ref
? Passing an IntPtr
as out
or ref
is really akin to passing a double pointer. It would actually seem more appropriate to pass the parameter as an IntPtr
.
The typical procedure is either to allocate the necessary memory in managed code and pass an IntPtr
representing that allocated memory, or IntPtr.Zero
to represent a null pointer. You do not need to pass the IntPtr
as out
or ref
in order to send data back to .NET; you only need to do that if the function you're calling would actually change the pointer's address.
Upvotes: 8
Reputation: 43317
I ran into this once. I ended up marshaling the pointer myself (see Marshal Members for the library functions to do so).
Upvotes: 0
Reputation: 161811
What's the intention of passing NULL
? Is it intended to call the method as usual, but to simply not set the output parameter?
In that case, I think I'd just wrap the extern method with an overload in C#. That overload (without the out
parameter) would be like this:
public void DoSomething()
{
IntPtr dummy;
DoSomething(out dummy);
}
Upvotes: 0
Reputation: 86134
I don't understand what the problem is....
This runs:
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;
}
Upvotes: 0