Search code examples
c#c++windows-mobilepinvoke

The correct C# PInvoke Signature for this C function


I've used the PInvoke Interop Assistant to generate a C# PInvoke Signature. I would like confirmation on this. I'm getting the "Can't find PInvoke DLL" message when invoking DLL. I am exporting the function. The DLL is present with executable. The message and cipherText are in/out blob of raw bytes and are the same buffer.

extern "C" int __declspec(dllexport) EncryptDeviceName(uint8 *message, uint8 *ciphertext, uint64 msglength)
{
    ...

    return 0;
}

It generated the following C# PInvoke Signature:

   /// Return Type: int
   ///message: UINT8*
   ///ciphertext: UINT8*
   ///msglength: UINT64->unsigned __int64
   [DllImport("HC128.dll", EntryPoint = "EncryptDeviceName")]
   public static extern int EncryptDeviceName(System.IntPtr message, System.IntPtr     ciphertext, ulong msglength);

I'll follow suggestions in the following similar question and provide an update.

UPDATE

My signature does work on Windows CE 6 with marshal alloc/dealloc. Tergiver's signature also works on Windows CE 6 and it does not require marshal alloc/dealloc.


Solution

  • There are many ways to write a p/Invoke declaration. The one given can be worked with, however it would require that you perform the Marshaller's job for it (allocating unmanaged memory, copying, and performing character encoding conversion).

    That native declaration doesn't provide enough information to guess at the required marshalling, which is probably why it's not there.

    What character encoding does the native function expect in message? Is ciphertext a blob of raw bytes or does it too have a character encoding (both in and out)?

    Updated

    If both message and cipherText are raw byte arrays, we can get them marshalled as

    [DllImport("HC128.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "EncryptDeviceName")]
     public static extern int EncryptDeviceName([In] byte[] message, [In, Out] byte[] ciphertext, ulong msglength);
    

    The In[Attribute] and Out[Attribute] tell the marshaller which way to perform a copy. [In, Out] is the default, I like to be explicit.