Tech Off Thread

8 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Help required with a custom PInvoke

Back to Forum: Tech Off
  • User profile image
    An_Angel

    Hi people... I could really do with someones expertise today!

    I have the following c dll that I need to call within C#

    extern "C" DECOMPRESSION_API int _stdcall Decompress_Event(unsigned char * inArr,   //IN:  BINARY DATA
                                                    int ArrSize,             //IN:  SIZE OF BINARY DATA
                                                    unsigned char * outArr,  //OUT: ASCII DATA
                                                    int maxOut)              //OUT: Maximum length of returned character string

    What I have got so far in c# is as follows:
    [DllImport("Decompression.dll",SetLastError = true,CharSet = CharSet.Auto)]
            private static extern int Decompress_Event([MarshalAs(UnmanagedType.LPArray)]char[] inArr, uint ArrSize, [MarshalAs(UnmanagedType.LPArray)]out byte[] outArr, uint maxOut);

    and the call to this is:
    Decompress_Event( x[0], (long)payloadReturned.ToArray().Length, outArray[0], tempVal);

    So far all I get is that it unbalances the stack... so I am guessing I have something wrong somewhere...

    Any help at all would be really appreciated!

          

  • User profile image
    Rossj

    An_Angel wrote:
    Hi people... I could really do with someones expertise today!

    I have the following c dll that I need to call within C#

    extern "C" DECOMPRESSION_API int _stdcall Decompress_Event(unsigned char * inArr,   //IN:  BINARY DATA
                                                    int ArrSize,             //IN:  SIZE OF BINARY DATA
                                                    unsigned char * outArr,  //OUT: ASCII DATA
                                                    int maxOut)              //OUT: Maximum length of returned character string

    What I have got so far in c# is as follows:
    [DllImport("Decompression.dll",SetLastError = true,CharSet = CharSet.Auto)]
            private static extern int Decompress_Event([MarshalAs(UnmanagedType.LPArray)]char[] inArr, uint ArrSize, [MarshalAs(UnmanagedType.LPArray)]out byte[] outArr, uint maxOut);

    and the call to this is:
    Decompress_Event( x[0], (long)payloadReturned.ToArray().Length, outArray[0], tempVal);

    So far all I get is that it unbalances the stack... so I am guessing I have something wrong somewhere...

    Any help at all would be really appreciated!

          


    Sorry my head isn't in gear at the moment, but shouldn't the output string be a stringbuilder instead?

  • User profile image
    An_Angel

    Just tried the StringBuilder, still no luck... any other ideas are welcome!

  • User profile image
    Sven Groot

    As I wrote in the Coffeehouse:
    [DllImport("whatever.dll")]
    public extern int Decompress_Event([MarshalAs(UnmanagedType.LPArray)]byte[] inArr, int ArrSize, [MarshalAs(UnmanagedType.LPArray)]byte[] outArr, int maxOut);

    Call as follows:
    byte[] inArr = GetInputFromSomewhereWhatever();
    byte[] outArr = new byte[maxOutputLength];
    Decompress_Event(inArr, inArr.Length, outArr, outArr.Length);

    Then to get the string from the result data
    string result = System.Text.Encoding.ASCII.GetString(outArr);
    (that's if the result is null-terminated, if it's not and for instance the function returns the number of chars, use the appropriate overload of GetString).

    It the out array should not be out, that would cause it to pass a pointer to the array (pointer to pointer), which the function doesn't want.

    EDIT: And char in C# is very different from char in C++, they're not the same size. Use byte in C#.

  • User profile image
    Maurits

    Sven Groot wrote:
    And char in C# is very different from char in C++, they're not the same size. Use byte in C#.


    /warning... tangential rambling follows

    Yup.

    C# char = C++ wchar; size is 16 bits, 2 bytes
    C# byte = C++ char; size is 8 bits, 1 byte

    MS C++ TCHAR = wchar or char depending on whether UNICODE is defined

    Alas, even a C# char is not big enough to hold all Unicode code points.  It's good enough for the BMP, but supplemental code points require two C# chars (a low surrogate and a high surrogate.)  C# is thus fundamentally UTF-16.

    This is why CharUnicodeInfo functions have a (string, index) overload as well as a (char) overload.  The (string, index) will check for surrogate pairs and analyze the supplemental code point thus encoded.

  • User profile image
    An_Angel

    Got it sorted!

    It went like this:
     [DllImport("Decompression.dll")]
            private static extern int Decompress_Event(byte[] inArr, UInt32 ArrSize, byte[] outArr, UInt32 maxOut);
          
    int errorno = Decompress_Event(x, (uint)payloadReturned.ToArray().Length, outArray, tempVal);


    Smiley

    Thanks Guys!

  • User profile image
    W3bbo

    An_Angel wrote:
    Got it sorted!

    It went like this:
     [DllImport("Decompression.dll")]
            private static extern int Decompress_Event(byte[] inArr, UInt32 ArrSize, byte[] outArr, UInt32 maxOut);
          
    int errorno = Decompress_Event(x, (uint)payloadReturned.ToArray().Length, outArray, tempVal);




    Thanks Guys!


    Now for bonus points, guess the application An_Angel is developing! Big Smile

    My money is on diving equipment.

  • User profile image
    An_Angel

    Nope it's not a dive equipment software of any kind.... It's non-sports related.... it's all about data decompression and boring stuff... you really wouldn't want to know what it is for coz it's that boring!

    Smiley

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.