Calling Native APIs from Managed Code - c#

I am developing a Windows Mobile application using WM6 SDK. The application is a Managed code (using C#) & I would like to know the steps to be taken in order to call native functions.
Thanks for the help,
Abdel Olakara

http://www.pinvoke.net/
That should do it.

You need to first declare the native APIs as static extern using DLLImport and then use them like normal methods. Example:
[DllImport("user32.dll", ExactSpelling = true)]
internal static extern IntPtr SetTimer(IntPtr hWnd, IntPtr nIDEvent, int uElapse, IntPtr lpTimerFunc);

Related

Load dynamic library and use functions inside the library

In C#, I am using an external dll, using loadLibrary, like this:
public class Utilities
[DllImport("kernel32", CharSet= CharSet.Auto, SetLastError=true)]
private static extern IntPtr LoadLibrary(string librayName);
[DllImport("kernel32", CharSet= CharSet.Auto, SetLastError=true)]
private static extern IntPtr GetProcAddress(intPtr hwnd, string procedureName);
public static LoadAssembliesAndMethods() {
string mainPath = AppDomain.CurrentDomain.BaseDirectory;
string path = Path.Combine(mainPath, "MyAssembly.dll");
IntPtr ptr = LoadLibrary(path);
// What to do next in order to get all the list of functions/methods/class in the library and use them?
}
The dll has no signature of Assembly (it's a 3rd party), so I cannot do
Assebly.LoadFile(path);
I need to get all of the functions/methods/class of the dll, and use some of them, using C#.
How can I do that.
If you want to list all methods inside a unmanaged dll this link help you:
C# get the list of unmanaged C dll exports
Update:
IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function =
Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate ))
as YourFunctionDelegate ;
function.Invoke(pass here your parameters);
you need to create delegates at coding or using DynamicModules for creating delegates at runtime
There is no common way to get the export list of a unmanaged library programatically.
See Is there a way to find all the functions exposed by a dll for more info

How to set Windows calendar type in C#

Is there a way to set the system calendar type using C#?
I found this function from Kernel32.dll:
BOOL SetCalendarInfo(
_In_ LCID Locale,
_In_ CALID Calendar,
_In_ CALTYPE CalType,
_In_ LPCTSTR lpCalData
);
How can I invoke this method within a C# application?
The Method signature should be the following:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool SetCalendarInfo(uint Locale, uint Calendar, uint CalType,
string lpCalData);
The pinvoke site is a starting point to show how to create c# method signatures for native methods but it may not always be accurate.
You will need to get familiarised with pinvoking in .net to understand how to interact with this method properly.
For additional information on the SetCalendarInfo method please read the MSDN documentation on it here http://msdn.microsoft.com/en-us/library/windows/desktop/dd374048(v=vs.85).aspx
The link below gives a good tutorial about platform invoking.
http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx

What exactly is this API and what is it doing?

I know you are gonna hate me for that kind of question. But could somebody tell me what the following code is doing?
I mean there are some libraries loaded, i get that. plus there are some methods, still I don't get it.
F.e.:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
Here is the code:
private static class API
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(
int idHook,
HookDel lpfn,
IntPtr hMod,
uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(
IntPtr hhk,
int nCode,
IntPtr wParam,
IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(
string lpModuleName);
}
You do not have to explain it to me line for line. At least give me some reference where I can read it up, please.
Thx in advance!
This code is using P/Invoke to allow C# code to call several Win32 API functions related to Windows Hooks.
The posted code only defines the methods; it doesn't call them, so it doesn't do anything by itself. It just allows you to use the methods from other parts of your code.
Here's an older MSDN article explaining P/Invoke and what's going on. Hopefully this helps you.
What the code is doing is allowing your managed C# code to call unmanaged Win32 API functions.
Here's also a tutorial on MSDN that walks you through the P/Invoke process of creating code like your question has.
DllImport is used to call unmanaged code/API in .Net/Managed code. All the code you've posted is trying to work with the window object of Win32 API.
References:
DLLImport
Win32 API
Win32 API to .Net API map
Take a look at this. Your program somewhere is installing a hook into windows hook chain to monitor some events.
The dllimport attribute itself lets the program to invoke win32 api functions like the previous answer mentions.

LoadLibrary call from MVC application running in IIS

I'm having trouble executing this line of code in my MVC application:
IntPtr hModule = LoadLibrary(BondProbeSettings.AssemblyFilePath);
The problem is that hModule is always 0.
If I run the same code with the same value for BondProbeSettings.AssemblyFilePath but from a console application instead of the MVC app hModule is non-zero.
Are there any security issues I need to consider?
The signature for LoadLibrary is:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern IntPtr LoadLibrary(string lpFileName);
Change the declaration to:
[DllImport("kernel32.dll", CharSet = CharSet.Auto), SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);
And your code to:
IntPtr hModule = LoadLibrary(BondProbeSettings.AssemblyFilePath);
if (hModule == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
Now you'll know why it doesn't work.
Yep you need to run the site assembly in full trust. I haven't configured this myself but I reckon you need:
to GAC the dll (meaning it has to be strongnamed)
to perhaps configure the application pool in IIS (assuming IIS) to allow full trust (?)
I'm on linux so I can't really help you with screenshots right now

P/Invoke problems with basic CRT functions (i.e., putchar, puts)

I've noticed something very strange. I was trying to call the CRT function "putchar", and was unable to get it to work. So I double-checked that I wasn't missing something, and I copied the code directly from the P/Invoke tutorial on MSDN to see if it worked.
http://msdn.microsoft.com/en-us/library/aa288468%28VS.71%29.aspx
You'll notice that they import "puts".
So I tested the exact code copied from MSDN. It didn't work! So now I got frustrated. I've never had this problem before.
Then I just so happened to run WITHOUT debugging (hit ctrl+f5), and it worked! I tested other functions which output to the console too, and none of them work when debugging but all work when not debugging.
I then wrote a simple C dll which exports a function called "PrintChar(char c)". When I call that function from C#, it works even if I'm debugging or not, without any problems.
What is the deal with this?
The Visual Studio hosting process is capable of redirecting console output to the Output window. How exactly it manages to do this is not documented at all, but it gets in the way here. It intercepts the WriteFile() call that generates the output of puts().
Project + Properties, Debug tab, untick "Enable the Visual Studio hosting process". On that same page, enabling unmanaged debugging also fixes the problem.
It's a bad example, using the C-Runtime Library DLL to call puts. Keep reading the tutorial as there is good info there, but try making Win32 API calls instead.
Here is a better introduction to p/invoke: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
It's old, but the information is still good.
Edited
My explaination was wrong.
I went looking for a correct explaination and I discovered that the C-Runtime puts method and the .NET Framework Console.Write method differ in how they write to the console (Console.Write works where the p/invoke to puts does not). I thought maybe the answer was in there, so I whipped up this demonstration:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
public static void Main()
{
int written;
string outputString = "Hello, World!\r\n";
byte[] outputBytes = Encoding.Default.GetBytes(outputString);
//
// This is the way the C-Runtime Library method puts does it
IntPtr conOutHandle = CreateFile("CONOUT$", 0x40000000, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
WriteConsole(conOutHandle, outputBytes, outputString.Length, out written, IntPtr.Zero);
//
// This is the way Console.Write does it
IntPtr stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(stdOutputHandle, outputBytes, outputBytes.Length, out written, IntPtr.Zero);
// Pause if running under debugger
if (Debugger.IsAttached)
{
Console.Write("Press any key to continue . . . ");
Console.ReadKey();
}
}
const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int WriteFile(IntPtr handle, [In] byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern bool WriteConsole(IntPtr hConsoleOutput, [In] byte[] lpBuffer, int nNumberOfCharsToWrite, out int lpNumberOfCharsWritten, IntPtr mustBeZero);
}
Both of those successfully output under the debugger, even with the hosting process enabled. So that is a dead end.
I wanted to share it in case it leads someone else to figuring out why it happens -- Hans?

Categories