In C# the extern modifier is used to declare a method that is implemented externally. Usually it is used with DllImport attribute to call some function in unmanaged code.
I wonder if there is a way to provide custom implementation of extern method?
To understand better the problem consider the following use case. I have a set of functions implemented in unmanaged code and I'd like to supply pointers to these function in run-time (during the loading of assembly).
The same thing DllImport attribute does, but I'd like to provide pointers by myself.
This is possible although you would need to PInvoke several things (LoadLibrary and GetProcAddress - see links below)... it is called "late binding native code"...
Some relevant links with source:
http://blogs.msdn.com/b/junfeng/archive/2004/07/14/181932.aspx
http://www.codeproject.com/KB/cs/dyninvok.aspx
http://pinvoke.net/default.aspx/kernel32/GetPRocAddress.html
http://www.pinvoke.net/default.aspx/kernel32.loadlibrary
You would need to use LoadLibrary and GetProcAddress
Related
I was re-reading through some .Net documentation today when I noticed that the first portion of the extern keywords documentation claims:
The extern modifier is used to declare a method that is implemented externally. A common use of the extern modifier is with the DllImport attribute when you are using Interop services to call into unmanaged code.
What caught my attention was that the document states that "a common use" of extern is that it is used with the DllImport attribute. This implies that there are other use-cases where DllImport is not required. I've not had to integrate many external, non-managed libraries into my applications but in all cases the linked methods were defined with DllImport.
I've searched multiple queries through Google and MSDN and I can't find a case or explanation of when the extern keyword would be used without defining the method as an external method import from an unmanaged dll.
How, and when, would you use the extern keyword without defining the [DllImport(...)] attribute on the method definition?
Please note, this is not specific to using extern when defining aliases. That is a different use of the keyword and that case is outlined in a different article within the MSDN C# language reference.
One case where I'd use it is if I were a Microsoft developer implementing a call to a method defined in the CLR itself. Like in GC._WaitForFullGCApproach:
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int _WaitForFullGCApproach(int millisecondsTimeout);
Note: no DllImport. Of course this is cheating a bit -- this is still a call to an unmanaged method, just not with an explicit reference to a DLL. Mere mortals cannot invoke such code, though, since it's valid only in the mscorlib assembly.
Another application of InternalCall is in interop types generated for COM:
namespace Microsoft.Office.Interop.Excel {
[DefaultMember("_Default")]
[ClassInterface(0)]
[ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents\0")]
[Guid("00024500-0000-0000-C000-000000000046")]
[TypeLibType(2)]
[ComImport]
public class ApplicationClass {
// ...
[DispId(302)]
[MethodImpl(MethodImplOptions.InternalCall)]
public virtual extern void Quit();
// ...
}
}
The attributes allow the runtime to resolve the method call as an invocation to a COM interface. This use of InternalCall is valid outside mscorlib, obviously. You would not typically write such code in C# yourself; it's generated on demand when you add a COM type library as a reference.
The C# language specification goes into slightly more detail than the MSDN:
The extern modifier is typically used in conjunction with a DllImport
attribute (ยง17.5.1), allowing external methods to be implemented by
DLLs (Dynamic Link Libraries). The execution environment may support
other mechanisms whereby implementations of external methods can be
provided.
From an implementation standpoint, marking a method extern only has the effect of setting the RVA (relative virtual address) of the method to 0, marking it as having no implementation. Attributes like DllImport (and MethodImpl) are necessary to describe to the runtime how to locate the method's actual implementation. This is described in secion I.9.4 of ECMA-335, "Method implementation metadata" (and DllImport and InternalCall seem to be the only ways currently available).
The C# compiler will allow you to mark a method as extern and not use any attribute to indicate where the implementation lives, but any type with such a method will result in a TypeLoadException at runtime.
I am currently using PInvoke to call some unmanaged functions from C++ in C#; specifically from PhysX 3.3.3. I am relatively new to PInvoke so I started with some simple methods. I can easily call functions that take no parameters but am having trouble calling any that do.
Starting simple, I used a function that passed in a boolean and discovered that booleans are non-blittable types so they must be marshaled. However, adding the boolean marshaling to the PInvoke signature still did not work.
[DllImport("PhysX3CommonCHECKED_x64.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?getReportAllocationNames#Foundation#shdfnd#physx##UEBA_NXZ")]
public static extern bool GetAllocationNames();
[DllImport("PhysX3CommonCHECKED_x64.dll", CallingConvention = CallingConvention.Cdecl,
EntryPoint = "?setReportAllocationNames#Foundation#shdfnd#physx##UEAAX_N#Z")]
public static extern void SetAllocationNames([MarshalAs(UnmanagedType.U1)]bool name);
When I call SetAllocationNames(true), I get an AccessViolationException. I have also tried using other member names for the UnmanagedType enumeration (e.g. U1, Bool) but to no avail.
I am loading the DLLs prior to calling the functions, I am using the correct mangled name as the entry point, and I am calling all parameters associated with this function (just one in this case). Is there something else I'm missing?
Unfortunately, it is mostly impossible to share C++ libraries with other C++ applications if they were compiled with a different compiler (and even worse, different versions of the same compiler) , yet alone using PInvoke.
Secondly, you're not even close at tackling this problem. C++'s calling convention (in x86) for methods (functions that belong to a class) is thiscall, which means that this (the class the method is called upon) is passed via the ecx or rcx register. cdecl doesn't pass one. Secondly, you didn't even define the appropriate classes...
What you should do is to write a C++ wrapper
Write functions, not methods (i.e - not bound to any class or struct), that do whatever you need to be done, and make sure that you know their calling convention (make it something conventional, like cdecl or fastcall). This way you can write C/C++ code to do the work for you, and write C# with PInvoke.
Okay, I think I understand now. After further research, it does seem that inherited functions are problematic for PInvoke. Many sources recommend flattening the C++ code to a C style interface. I will have to use a C++/CLI project instead. Thanks!
Have been trying all day and searching various sources but can't find a solution. I am calling an imported unmanaged dll function from c#.
C++ class looks like:
class MyModule
{
public:
MYMODULEDLL_API int __cdecl Init(int);
...
Defined in C# like this:
[DllImport("MyModule_x64.dll", EntryPoint =
"?Init#MyModule##QEAAHH#Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int Init(int len);
And calling like this:
Init(configFileName.Length);
I can see in the debugger that the proper function in the dll is being called, but the passed parameter is corrupted showing a completely different value than what was passed. This is happening for string parameters as well. Is there anyway to troubleshoot the marshalling of parameters between managed and unmanaged code?
You can`t use C++ classes using DLLImport or PINVOKE, because it is suitable only for C style functions.
If you want to use C++ class in C#, you need to go with C++/CLI. You can create an unmanaged dll in native C++ and then create a simple C++/CLI wrapper which calls methods from native dll. After that you can simply add a C++/CLI managed dll to the project and use it as C# class without any DllImports and PINVOKEs. It will be a very flexible soltuion which is easy to expand. On MSDN you can find examples how to use C++/CLI.
I have an unmanaged DLL that exports C style non-member functions for creating (say CreateObject) and destroying objects (DestroyObject). CreateObject returns a C++ class as a void*, which in the unmanaged code is cast to a known interface (defined only in a header file) and worked with. Is there a way to call methods on the IntPtr that is returned to me by CreateObject?
Dumpbin /EXPORT doesn't show me any methods of the C++ class, just the exported C functions (mentioned above).
I would like to avoid having to write C++ CLI code or a purely unmanaged DLL that simply exposes methods on this class as function wrappers if possible
This is Windows/MSVC only, so answers that restrict compatibility to Windows/MSVC are fine.
NOTE: I'm talking about invoking C++ methods on a void*/IntPtr returned by a C function - not P/Invoking the C functions.
Thanks!
If you are ruling out C++/CLI, and only have an IntPtr containing the address of the instance then you have few options remaining.
As I see it you are left with p/invoke. In order to call a method you'll need to export it from your unmanaged code. You'll also need to be careful about the calling convention. Commonly it will be __thiscall. When you write the p/invoke, you must explicitly add the this pointer as the first parameter.
This is fine so far as it goes. But you'll not be able to export virtual methods this way. You cannot call them using p/invoke.
Frankly though the cleanest and simplest way to do this interop is with our old friend, tried and tested COM. This very scenario is just what it was designed for. C++ classes are not designed for interop across compiler/language boundaries. That's what COM is for.
Microsoft has a very nice Windows API wrapper included in .NET framework. It is stored in Microsoft.Win32.UnsafeNativeMethods , Microsoft.Win32.SafeNativeMethods and Microsoft.Win32.NativeMethods.Unfortunately they aren't accessible because they are declared as private. Is there a way of accessing them easily?
Most method definitions in those classes (if not all) are extern declarations with DllImport attributes that refer to functions in the Windows API through P/Invoke. In doesn't matter where these declarations reside. You can create your own class named UnsafeNativeMethods or SafeNativeMethods and put declarations referring to the same Windows API functions in there. You'll find the signatures of many Windows API functions for C# on pinvoke.net.
For what it's worth I always thought there should have been a kernel32.interop.dll etc with the static methods already DllImport'ed. But I've resorted to creating my own on an as-needed basis. Over the years I've found I rarely use more than a handful of them but it's such a pain in the ass when I need an API that I haven't imported yet.
Most of the functionality contained in these classes is exposed by the .Net framework itself; you should search (or ask here) before making API calls.
To answer your question, no.
The best you can do is to copy them from Reflector or the reference source.
The reason could be the security impact of SuppressUnmanagedCodeSecurityAttribute. Check Move P/Invokes to NativeMethods class