I wanted to answer this question and thought I would look inside of the Array source code to see how it is implemented. Therefore, I looked in .NET source code for the CreateInstance method and found that it calls an external method whose body is a semi-colon and implemented elsewhere. Here is what it looks like:
private unsafe static extern Array
InternalCreate(void* elementType,int rank,int *pLengths,int *pLowerBounds);
Question:
How do I find where the implementation for the above external method is?
To find the source code for any extern methods, do the following:
Find the name of the extern method. In my case it is InternalCreate.
Go here and find the mapping of the method to the external method. In my case I needed to find InternalCreate and here is what the mapping looks like. The name of the class is ArrayNative and the method is CreateInstance:
FCFuncElement("InternalCreate", ArrayNative::CreateInstance)
Find the mapped class here. In my case I needed arraynative and I needed the method CreateInstance. The implementation is right there and I am copying it here but removing the body for brevity:
FCIMPL4(Object*, ArrayNative::CreateInstance,
void* elementTypeHandle, INT32 rank, INT32* pLengths, INT32* pLowerBounds)
{
//...
}
There you will find the implementation and study the code.
Related
When we import legacy dlls in C# we use something like the following notation:
[DllImport("user32.dll")] // Why am I enclosed in "["s
static extern int MessageBoxA(int hWnd, string strMsg, string strCaption, int iType);
OR also:
[MarshalAs(UnmanagedType.LPStr)] // <-- What in the world is it?
string arg1,
as mentioned here
However, this notation is not exclusively used for interop Services only like here, like:
[Conditional("DOT")] // <--- this guy right here!
static void MethodB()
{
Console.WriteLine(false);
}
but it is not listed as a preprocessor directive at msdn
What is this notation called? Where can I find literature or documentation for it?
These are attributes. They're not "preprocessor" parts of the language - unlike things like #if, #pragma (which are still not really handles by a preprocessor, but are meant to be thought of that way).
Basically, attributes allow you to express compile-time constant metadata about types, fields, methods, parameters, and return values. That metadata can then be retrieved at execution time via reflection.
One important thing to know in terms of finding documentation: the C# compiler will attempt to resolve an attribute like this:
[Foo]
as both Foo and FooAttribute. So your [MarshalAs] example actually refers to MarshalAsAttribute. Conventionally, all attributes end with an Attribute suffix.
Given the following c++ class in foo.dll
class a{
private:
int _answer;
public:
a(int answer) { _answer = answer; }
__declspec(dllexport) int GetAnswer() { return _answer; }
}
I would like the pInvoke GetAnswer from C#. To do that, I use the following method:
[DllImport("foo.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint= "something")]
public static extern int GetAnswer(IntPtr thisA);
And I pass in an IntPtr that points to an a (that I got from somewhere else, it's not important). CallingConvention = CallingConvention.ThisCall makes sure it's handled correctly
What's cool about this question is that I know I'm right so far because it's already working great! Using Depends.exe, I can see that "GetAnswer" is exported as ?GetAnswer#a##UAEHXZ (Or something close - the point being that it's been name mangled). When I plug the mangled name into the "something" for the EntryPoint everything works great! It took me about a day before it dawned on me to use Depends.exe, so I'm going to leave this here as a help to anybody who has a similar issue.
My REAL Question is: Is there any way to disable C++ name mangling on GetAnswer so that I don't need to put the mangled name in as my entry point. Having the mangled name in there seems like it could break, because my understanding of name mangling is that it can change if the compiler changes. Also it's a pain in the butt to use Depends.exe for every instance method that I want to pInvoke.
Edit: Forgot to add what I've tried:
I don't seem to be able to put extern "C" on the function declaration, although I can stick it on the definition. This doesn't seem to help though (which is obvious when you think about it)
The only other solution I can think of is a c-style function that wraps the instance method and takes an instance of an a as a parameter. Then, disable name mangling on that wrapper and pInvoke that. I'd rather stick with the solution that I already have, though. I already told my co-workers that pInvoke is great. I'm going to look like an idiot if I have to put special functions in our c++ library just to make pInvoke work.
You cannot disable mangling for a C++ class method, but you may well be able to export the function under a name of your choice using /EXPORT or a .def file.
However, your entire approach is brittle because you rely on an implementation detail, namely that this is passed as an implicit parameter. And what's more, exporting individual methods of a class is a recipe for pain.
The most sensible strategies for exposing a C++ class to .net languages are:
Create flat C wrapper functions and p/invoke those.
Create a C++/CLI mixed mode layer that publishes a managed class that wraps the native class.
Option 2 is preferable in my opinion.
You may be able to use the comment/linker #pragma to pass the /EXPORT switch to the linker which should allow you to rename the exported symbol:
#pragma comment(linker, "/EXPORT:GetAnswer=?GetAnswer#a##UAEHXZ")
Unfortunately, this does not resolve your need to look up the mangled name using depends or some other tool.
You do not have to disable the mangled name which actually contains lots of information of how the function itself is declared, it basically represents the whole signature of the function after the function name gets de-mangled. I understand you already found a word-around and the other answer has been marked as a correct answer. What I am writing below is how we can make it work as you desired.
[DllImport("foo.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint = "#OrdinalNumber")]
public static extern int GetAnswer(IntPtr thisA);
If you replace "#OrdinalNumber" with the real ordinal number of GetAnsweer, such as "#1", it will work as you desired.
You may just consider the EntryPoint property is the same as the function name we pass to GetProcAddress where you can either pass the function name or the ordinal number of the function.
Your approach to calling non-static function members of a C++ class is indeed correct and thiscall is used correctly and that is exactly thiscall calling convention comes in play in C# P/Invoke. The issue with this approach is that you will have to look into the DLL's PE information, Export Function Information and find out the ordinal number for each function you would like to call, if you have a big number of C++ functions to call, you may want to automate such a process.
From the Question Author: The solution I actually went with
I ended up going with a c-style function that wraps the instance method and takes an instance of an a as a parameter. That way, if the class ever does get inherited from, the right virtual method will get called.
I deliberately chose not to go with C++/CLI because it's just one more project to manage. If I needed to use all of the methods on a class, I would consider it, but I really only need this one method that serializes the class data.
I am currently browsing decompiled C# IL (with ILSpy) to get an impression on how some of the methods from System.Runtime.InteropServices are (could be) implemented.
When I wanted to check how Marshal.Copy() is implemented, I found out that it only calls CopyToNative(), which is defined as follows:
// System.Runtime.InteropServices.Marshal
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void CopyToNative(object source, int startIndex, IntPtr destination, int length);
Where is it implemented?
Is there any chance to look at its (decompiled) source code?
If not, does anyone have a clue on how it could be implemented?
The MethodImplAttribute and extern keyword indicate that this function is internal to the .NET runtime itself. This function is almost certainly implemented in C or C++ in the runtime's source code.
Without access to the runtime's source code your only real option is to disassemble this particular function and examine the assembly. (Please note that doing this may violate the EULA of your runtime.)
You might consider looking at Mono's source code to get a look at one possible implementation.
Marshal.Copy() implementations
copy_to_unmanaged() runtime-internal implementation
In C++ I have some code that requires a const char * to be passed in:
void Load(const char *filename)
If I try using String as MSDN seems to suggest:
[DllImport("foo.dll")]
protected static extern void Load(String filename);
I end up getting an exception stating that the call has an unbalanced stack, due to a mismatch between the managed P/Invoke call and the actual C++ function signature.
What would be the appropriate C# function signature I would need to use? I've tried googling for the answer but I'm not coming up with anything.
The solution: It turns out that the reason why I was getting an "unbalanced stack" error was because the test code I was running called for a file that didn't actually exist in the directory. With CallingConvention=cdecl, and the file in the appropriate place, the issue was resolved.
The problem is the calling convention. And while we're at it, you probably need to specify the character set since it may assume Unicode otherwise:
[DllImport("foo.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Cdecl)]
protected static extern void Load(String filename);
You could add the MarshalAsAttribute like e.g.
[DllImport("foo.dll")]
protected static extern void Load(
[MarshalAs(UnmanagedType.LPStr)]string filename);
You can pass one of the UnmanagedType enumeration values to the MarshalAsAttribute constructor.
See also this overview article over at Code Project.
In another question I asked, a comment arose indicating that the .NET framework's Array.Copy method uses unmanaged code. I went digging with Reflector and found the signature one of the Array.Copy method overloads is defined as so:
[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);
After looking at this, I'm slightly confused. The source of my confusion is the extern modifier which means (MSDN link):
The extern modifier is used to declare
a method that is implemented
externally.
However, the method declaration is also decorated with a MethodImplOptions.InternalCall attribute, which indicates (MSDN link):
Specifies an internal call. An
internal call is a call to a method
that is implemented within the common
language runtime itself.
Can anyone explain this seemingly apparent contradiction?
I would have just commented on leppie's post, but it was getting a bit long.
I'm currently working on an experimental CLI implementation. There are many cases where a publicly exposed method (or property) can't be implemented without knowledge of how the virtual machine is implemented internally. One example is OffsetToStringData, which requires knowledge of how the memory manager allocates strings.
For cases like this, where there is no C# code to express the method, you can treat each call to the method in a special way internal to the JIT process. As an example here, replacing the call byte code with a ldc.i4 (load constant integer) before passing it to the native code generator. The InternalCall flag means "The body of this method is treated in a special way by the runtime itself." There may or may not be an actual implementation - in several cases in my code the call is treated as an intrinsic by the JIT.
There are other cases where the JIT may have special information available that allows heavy optimization of a method. One example is the Math methods, where even though these can be implemented in C#, specifying InternalCall to make them effectively intrinsics has significant performance benefits.
In C#, a method has to have a body unless it is abstract or extern. The extern means a general "You can call this method from C# code, but the body of it is actually defined elsewhere.". When the JIT reaches a call to an extern method, it looks up where to find the body and behaves in different ways per the result.
The DllImport attribute instructs the JIT to make a P/Invoke stub to call a native code implementation.
The InternalCall flag instructs the JIT to treat the call in a self-defined way.
(There are some others, but I don't have examples off the top of my head for their use.)
InternalCall means provided by the framework.
extern says you are not providing code.
extern can be used in 2 general situations, like above, or with p/invoke.
With p/invoke, you simply tell the method where to get the implementation.