Why does DllImport require an Identifier? - c#

I'm a little confused.
In the code:
[DllImport("library.dll")]
public static extern void function(int x);
why is the x required? Shouldn't the int be enough as this is just a definition and not a declaration?

Its the C# Syntax, the same goes for methods in interface.
Probably the biggest reason is, that it adds clarity to the code. Parameter name may tells about the expected value in method

Related

What is the difference between "this ref" and "ref this" when talking about C# 7.2 ref extension methods?

Consider the following extension methods:
public static void Toggle(this ref bool #bool) => #bool = !#bool;
public static void Toggle2(ref this bool #bool) => #bool = !#bool;
These simply toggle a ref boolean variable value. Testing:
class Foo
{
private bool _flag;
public void DoWork()
{
_flag.Toggle();
Console.WriteLine(_flag);
_flag.Toggle2();
Console.WriteLine(_flag);
}
}
We get:
True
False
The question: Is there any hidden difference in choosing one syntax or the other?
Nope, they're exactly the same, just as (now) you can write an interpolated verbatim string literal using either $# or #$.
There is no difference. These are called modifiers, and their order in the specification is not defined.
You can read the section on method parameters in C# Language Specification here:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#method-parameters
It lists out the different options and defines how they interact and mix, but says nothing about what order you must use.
Although they're exactly the same according to the language specification. I have found a difference that has to do more to the compiler and that may be a compiler bug. The setup to reproduce this is with Visual Studio 2019. The bug may be in other compilers versions, I really did not research more about this.
If your language level is 7.2 or above, then both syntax work just the same way. However if your project is working with language level 7.0 or 7.1 then the following will compile:
struct S {}
static class Extensions
{
static void M(this ref S s) {}
}
But if we change the order of the modifiers like here:
static class Extensions
{
static void M(ref this S s) {}
}
You will get the following compiler error message:
error CS8107: Feature 'ref extension methods' is not available in C# 7.0. Please use language version 7.2 or greater.
The weird part is that although static void M(this ref S s) compiles, there is no way of consuming the method as an extension method of S:
s.M() //error CS8107 here
But you are able to call the method using the traditional static syntax:
Extensions.M(ref s)
So, although there is no difference regarding the language specification, for those using the Roslyn compiler it is better to use this ref instead of ref this since that would be backwards compatible with 7.0 and 7.1 as long as the bug is there IMO
I reported here the lack of information about ref extensions methods for structs, and some other guy reported to Roslyn the issue.
I am not marking this answer as THE answer since I thinke those of #Jon Skeet and #Joel Coehoorn are more accurate regarding the language. But I think this is useful info anyway

C# - Why do I need to initialize an [Out] parameter

I have a couple of methods imported from a native .dll, using the following syntax:
internal static class DllClass {
[DllImport("Example.dll", EntryPoint = "ExampleFunction")]
public static extern int ExampleFunction([Out] ExampleStruct param);
}
Now, because I specified param as [Out], I would expect at least one of the following snippets to be valid:
ExampleStruct s;
DllCass.ExampleFunction(s);
ExampleStruct s;
DllCass.ExampleFunction([Out] s);
ExampleStruct s;
DllCass.ExampleFunction(out s);
However, none of them works. The only way I found to make it work was by initializing s.
ExampleStruct s = new ExampleStruct();
DllCass.ExampleFunction(s);
I have managed to fix that by rewriting the first snippet to the following code, but that feels kinda redundant.
internal static class DllClass {
[DllImport("Example.dll", EntryPoint = "ExampleFunction")]
public static extern int ExampleFunction([Out] out ExampleClass param);
}
I've read What's the difference between [Out] and out in C#? and because the accepted answer states that [Out] and out are equivalent in the context, it left me wondering why it didn't work for me and if my "solution" is appropriate.
Should I use both? Should I use only out? Should I use only [Out]?
The OutAttribute determines the runtime behavior of the parameter, but it has no impact at compile time. The out keyword is required if you want to use compile-time semantics.
Using just the out keyword will change the runtime marshaling, so the OutAttribute is optional. See this answer for more info.
Are you initializing it to a value inside the function? That's where the requirement comes in: out parameters must be assigned to at least once within the function which declares the parameter.

Wrong overload method called

I have written COM component in C#. Interface methods are declared in following manner:
[ComImport,
Guid("7D37EE00-143E-40DF-B177-BF091D7CD36A"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMonogramServiceHost
{
void Send(
[In, MarshalAs(UnmanagedType.BStr)] string text);
void Send([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]byte[] data,
[In, MarshalAs(UnmanagedType.I4)] int length);
}
These methods are called from C++ code. This same interface declared in C++ is:
DECLARE_INTERFACE_(IMonogramServiceHost, IUnknown)
{
STDMETHOD(Send)(BSTR text);
STDMETHOD(Send)(uint8 *buf, int length);
};
I am calling second method. Its parameter is simply unsigned char array whose length is defined by parameter 'length'. By some unknown reason code steps into method 'void Send(string text)'. After returning from COM method debugger displays following error message:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
When I rename method to ASend correct version is called. Why is this happening? I dont see logic in this.
COM doesn't support function overloading. It isn't that clear how you are making the call, but late binding will certainly fail. IDispatch::GetIDsOfNames() is going to return the wrong dispid when asked for "Send". That's not strongly indicated in this case since you derive from IUnknown. But in itself is enough reasons to give these methods distinct names.
I'd suggest SendText vs SendBytes. Quite justified in itself, bytes and characters are not at all equivalent in Unicode.
A C# char array is a C++ uint16 array, not a uint8 array. The second signature is a mismatch.

Purpose of C# constructor extern modifier

What is the Purpose of C# constructor extern modifier?
I know about usage of extern METHODS to invoke Win32 functions, but what about CONSTRUCTORS?
Please give the practical example.
Note this:
class MyClass
{
public extern MyClass();
}
I believe one use/purpose of an extern ctor is to have the constructor implemented within the CLR itself. if you disassemble mscorlib.dll using Reflector and look at the System.String type, you'll see:
[MethodImpl(MethodImplOptions.InternalCall)]
public extern String(char[] value);
Which basically tells us that the (char[]) ctor for the string class is externally implemented, as part of the .net runtime.
The c# spec here indicates that apart from private, internal, protected and public, extern may be used and that this is standard external reference - see here. This to me says that the contstructor is linked into the class at a later time. Just like the PInvoke calls are. There's nothing, I'm guessing, stopping the c# compiler implementer allowing linking of external .net .modules containing said external constructors.
I cannot give an example, but I suspect one way woud be to implement the constructor in MC++, or in fact just a simple IL .module.

p/invoke C function that returns pointer to a struct

How do I declare in C# a C function that returns a pointer to a structure?
I believe following is one way to do that, followed by Marshal.PtrToStructure to get actual structure value.
// C-function
SimpleStruct * Function(void);
// C# import
[DllImport("MyDll.dll")]
public static extern IntPtr Function();
Am I correct about that?
Are there other ways to accomplish the same? (It would be OK to get struct back by value)
Since the function returns a pointer (hopefully not a locally allocated one?) your best bet is to manually marshal it (via Marshal.PtrToStructure).
If it were a parameter you could create a managed version of the structure using the PInvoke Interop Assistant then pass it via ref or out.
Caveat: this will only work if the pointer returned is to memory already managed by the CLR
I believe what you are looking for is
// C# import
[DllImport("MyDll.dll")]
[return : MarshalAs(UnmanagedType.LPStruct)]
public static extern StructureName Function();
[StructLayout(LayoutKind.Sequential)]
public class StructureName {}
This should eliminate the need for any manual Marshal.PtrToStructure calls. Depending on what your structure contains, you may need to tag some fields with MarshalAs attributes as appropriate. MSDN has a good example of this.
I am not an expert here at all, but I happened to be looking at a piece of code (that i don't understand completely mind you) that is doing this same thing.
Here is what they are doing
[DllImport("")]
private static extern short MethodName([In,Out] ref StructureName variable);
and then on the structure they have the following attribute
[StructLayout(LayoutKind.Sequential, Size = #)]
public struct StructureName {}
I think the part you are looking for is the [In,Out] part, and since it's being passed via ref, you should be getting the same data back.
marked as community wiki so people can fix this if wrong.

Categories