.NET signature to p/invoke GetSystemDEPPolicy function - c#

I can't find any example signatures for .NET to use this function (GetSystemDEPPolicy).
http://msdn.microsoft.com/en-us/library/windows/desktop/bb736298(v=vs.85).aspx
It's a fairly simple function but I don't know how to create the signature to call it. Can someone please help?

GetSystemDEPPolicy is defined as
DEP_SYSTEM_POLICY_TYPE WINAPI GetSystemDEPPolicy(void);
and DEP_SYSTEM_POLICY_TYPE is an enum (see winbase.h assuming you have the C++ components installed in your development environment - if not try winbase.h) and enums in C default to int, as such I would go with
[DllImport("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern int GetSystemDEPPolicy();
May I recommend you follow this tutorial on PInvoke

Related

How to natively call this function from a DLL?

I have used DLL Export viewer to try and find the functions that are in this DLL, I have found a list of functions and here it is:
public: int __thiscall CSTVdsDisk::GetPartitionCount(void);
the question is within in C# I am not able to call the function using either:
[DllImport("Some.dll",
ExactSpelling = true,
EntryPoint = "GetPartitionCount",
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
or:
[DllImport("Some.dll",
ExactSpelling = true,
EntryPoint = "CSTVdsDisk::GetPartitionCount",
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
private static extern int GetPartitionSize();
They all fail. Is there something that I am doing wrong? Can anyone help? Thanks!
You can't call that function using P/Invoke. The __thiscall calling reference means that this function is a class member function. It is a member function of the CSTVdsDisk class.
To be able to call the function you will have to create an instance of the CSTVdsDisk class and call GetPartitionCount from that instance.
You'll have to do that in C++ or C++/CLR as you can't create a C++ class in C#. See also Create unmanaged c++ object in c#.
Based on the name, that appears to be a C++ class method. That is going to make it very difficult to call that method directly from P/Invoke for two reasons:
You need to find the "real" name; the Export Viewer is apparently showing up the unmangled name, but the actual C++ function name will look much uglier, like #0GetPartitionCount#CSTVdsDisk##QPBAEXA or similar. You may need to use a lower-level tool like dumpbin to find that name.
You need to fake the "thiscall" style call; this means you need to pass an instance of a C++ class as the first parameter. This is only going to work if the C++ class constructor is also exposed from the DLL; in which case, you can call the class constructor, store the result in an IntPtr, and pass it to every subsequent call. (If the constructor is exposed as a DLL export its mangled name will start with ??, like `??0CSTVdsDisk##QAE#ABV0##Z
This CodeProject article shows you how to do most of that, but it's pretty fragile, so expect problems. I'd strongly suggest you look for a non-C++ library that does something similar, or at least one that's designed to be usable from C code.
In your native code, make sure you're exporting the function. By default you function wont be listed in the Exports table so you need to mark it so that the compiler knows to export it. You also need to mark the function as
extern "C"
so that the compiler doesn't mangle the name.
Typically I define the following macro:
#define DLLEXPORT extern "C" __declspec(dllexport)
to handle all of this, and then simply declare exported functions like:
DLLEXPORT __cdecl int Example(int x, int y)
If you find you're still having troubles with the name, try using a free PE explorer program on the dll and checking the exported function table for the correct name.

can't call C++ function from C#

I have a DLL with a set of functions. The DLL was used with "themidia" to make it safe.
When I try to call the functions, C# spits out errors due to the functions names.
[DllImport("safety.dll", CallingConvention=CallingConvention.StdCall, ExactSpelling=true)]
private static extern IntPtr _encryptLogin#8(string string_0, string string_1);
If I remove the #8 and remove ExactSpelling=true, it just returns an exception saying no entry point.
What exactly am I doing wrong?
Remove the "#", and in your attribute add EntryPoint="_encryptLogin#8"
As an alternative to specifying EntryPoint as rfmodulator suggested, you can use extern "C" in your C++ source, which will make the exported function names the same as their names in your C++ source.
C++ compiler normally mangles the names of functions, so that you can have overloaded functions (functions with the same name bu different parameters).

how to use cdecl callback with pinvoke

I have a c library that has cdecl callbacks. How can I use these from c#.
Everything seems to say that they must be stdcall callbacks
to be clear:
delegate int del();
[dllimport("mylib.dll",CallingConvention=CallingConvention.Cdecl)]
public static extern int funcwithcallback(del foo);
where del must be called cdecl-wise
Take a look at this. The functionality has been around since 1.1 so it should cover whatever .NET version you are using. You just have to specify the CallingConvention.
CallingConvention Documenation at MSDN
You can also look at this article on Code Project:
Using the _CDECL calling convention in C#
EDIT: Also, Here is a example from FreeImage.NET.
static FreeImage_OutputMessageFunction freeimage_outputmessage_proc = NULL;
DLL_API void DLL_CALLCONV
FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf);
Then on the C# side, simply:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FreeImage_OutputMessageFunction(FREE_IMAGE_FORMAT
format, string msg);
[DllImport(dllName, EntryPoint="FreeImage_SetOutputMessage")]
public static extern void SetOutputMessage(FreeImage_OutputMessageFunction
omf);
Compile with .NET 2.0, use 2005 compiler!!
Reverse the argument direction.
It works due to some safeguard code added by the 2005 compiler.
EDIT: Don't try this if you can possibly make a shim in native code.

Dynamically Loading DLLs at Runtime

I'm working on a C# application that supports two communications interfaces, each supported by its own DLL. Each DLL contains the same function names, but their implementation varies slightly depending on the supported interface. As it is, users will typically have only one DLL installed on their machine, not both. The DLL for the old interface is imported like this:
[DllImport("myOldDll.dll",
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int MyFunc1( void );
public static extern int MyFunc2( void );
public static extern int MyFunc3( void );
Would this be a valid way to attempt to bring in either DLL?
[DllImport("myOldDll.dll",
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
[DllImport("myNewDll.dll",
CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int MyFunc1( void );
public static extern int MyFunc2( void );
public static extern int MyFunc3( void );
Ideally, I suppose it would be nice to detect a missing DLL and load the second DLL if the attempt to load the first fails. Is there a graceful way to do that?
How about doing a P/Invoke to `LoadLibrary'?
In .NET 1.1 you would need to create a proxy unmanaged DLL (write it in C or Delphi or ... ) and call it's methods, and that unmanaged DLL would do the rest. In .NET 2.0 and later you use Assembly.LoadFile() and further. Not as elegant as just declarations you attempted to use, and requires quite a lot of coding. So I'd suggest a proxy way if possible.
Perhaps you should give the methods imported from either DLL different names, and then have a delegate in your program that you point to one or the other (whichever is appropriate), and only call the delegate.
It sounds like you would be best served re-architecting to a modular plugin style interface.
There are a billion and a half examples of this on the web, like this one. In a nutshell though, you use LoadAssembly() on a directory of DLLs, then cast back to your common base interface.
I think I found a workable solution:
C# check that a file destination is valid
Thanks, everyone, for your input!

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