Search code examples
c#pinvoke64-bitdllimporttype-conversion

DataType between different process and architectures - Writing a correct DllImport


I have a main application written in C# that runs as a x64 bit application, it communicates through dll import with a standard native unmanaged C/C++ dll of which I have also the header.

I need help for setting out the correct dataTypes.

So i expose one of the methods I have to call and the data types defined in the dll header.

typedef int DLL_IMP_EXP (* INJECTDLL)(HANDLE, DWORD, LPCTSTR, DWORD, HINSTANCE *);

HANDLE is defined as void*

DWORD is defined as unsigned long

LPCTSTR is defined as __nullterminated CONST CHAR*

HINSTANCE gives me this line for definition: DECLARE_HANDLE(HINSTANCE); ?!?

Using Unicode declaration of the function: LPCWSTR is defined as __nullterminated CONST WCHAR*

Please help me writing the correct declaration of the:

[DllImport ("Inject.dll", VariousParameters)]
public static extern int InjectDll(CorrectDataTypes);

Compiling VariousParameters if needed, and obviously CorrectDataTypes.


Solution

  • And IntPtr is used for a pointer or a handle - it will be 32 bits on a 32 bit system and 64 on a 64 bit system. So if you have anything that is a raw pointer or a handle use an IntPtr and it will work correctly on both systems. However your last parameter is a pointer to a handle - use a ref to handle the pointer. So in this case since it's a pointer to a handle, the parameter will be a ref to an IntPtr.

    For standard numeric types, those will map directly to the .NET data types - you can get more details at MSDN.

    Null terminated strings are handled correctly, although you'll need to specify whether it uses ANSI or Unicode strings.

    Finally P/Invoke assumes a StdCall calling convention (which is what the Windows API uses). If you're not using that, which the function prototype would include STDCALL or __stdcall in it, the standard C calling convention is Cdecl. Although you'll have to find out what DLL_IMP_EXP expands to.

    So your P/Invoke declaration should be:

    [DllImport ("Inject.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
    public static extern int InjectDll(IntPtr handle, uint dword, string str, uint dword2, ref IntPtr hInstance);