C# and void pointers

2020-04-04 04:22发布

问题:

I am writing my first C# application, but as luck would have it I must use void pointers (working with a DLL which returns handles). From what I read there are a few options:

  1. Unsafe code, for example see http://www.c-sharpcorner.com/UploadFile/gregory_popek/WritingUnsafeCode11102005040251AM/WritingUnsafeCode.aspx

  2. In the C# program writing in my function declerations IntPtr instead of void*. e.g.: public static extern char SupportsWhatever(IntPtr h);

  3. Using ref, e.g.: public static extern char SupportsWhatever(ref h);

It should also be noted that I need to marshal information back and forth between the DLL and C# application.

The unsafe option was the first that popped up on Google, but for some reason writing the keyword unsafe before all my functions just doesn't feel right.

Any recommendations?

回答1:

Typically, for marshaling situations, using IntPtr would be the preferred approach here. It is allowed in safe code, and makes it very clear that your intention is marshaling a pointer back and forth.

This is how much of the BCL represents handles. For example, you can construct a Cursor from an IntPtr representing the native handle.



回答2:

The basic rule is if you need to interact with it as a pointer in c# use unsafe code/pointers. If you can treat it as an opaque handle use an IntPtr. You would use ref if you need to pass a pointer to a structure to unmanaged code.



回答3:

Unsafe is an instruction to compiler that there will be pointers in this context. From MSDN

In the common language runtime (CLR), unsafe code is referred to as unverifiable code. Unsafe code in C# is not necessarily dangerous; it is just code whose safety cannot be verified by the CLR. The CLR will therefore only execute unsafe code if it is in a fully trusted assembly. If you use unsafe code, it is your responsibility to ensure that your code does not introduce security risks or pointer errors.

I have used it since .net 1.1 while using an C++ API in C# which used to talk to mainframes through COM Port of PC :)