Jump to content

dllcall to lzo failed


Recommended Posts

Hi, I'm trying to use dllcall on lzo dll for compress files inside of my program But I have not succeeded yet
LZO decompress work without any problem, but when I try to compress a file autoit give me this error every time AutoIt3.exe ended.rc:-1073741819 I know I'm calling function right (I hope), but I don't know why its not working

here is my code

Func _lzo1cCom($handle, $buffer)
  Local $inputSize = BinaryLen($buffer)
  Local $_data = DllStructCreate("BYTE[" & $inputSize & "]")
  DllStructSetData($_data, 1, $buffer)
  Local $OutputLen = $inputSize + $inputSize / 64 + 16 + 3 + 4
  Local $tCom = DllStructCreate("BYTE[" & $OutputLen & "]")
  Local $compressedSize = 0

  $compressedBuffer = DllCall($handle, "INT", "lzo1c_1_compress", _
          "ptr", DllStructGetPtr($_data), _ ;~ src data that I want to compress
          "uint", $inputSize, _             ;~ size of src data
          "ptr", DllStructGetPtr($tCom), _  ;~ buffer for compressed data
          "int*", $compressedSize)          ;~ compressed file size
EndFunc

here is c# code that working without any problem

private const string LzoDll64Bit = @"lib64\lzo2_64.dll";

[DllImport(LzoDll64Bit)]
private static extern int lzo1x_1_compress(byte[] src, int src_len, byte[] dst, ref int dst_len, byte[] wrkmem);

private byte[] _workMemory = new byte[16384L * 4];

public byte[] Compress(byte[] src)
{
    byte[] dst = new byte[src.Length + src.Length / 64 + 16 + 3 + 4];
    int outlen = 0;
    lzo1x_1_compress(src, src.Length, dst, ref outlen, _workMemory);
    byte[] ret = new byte[outlen + 4];
    Array.Copy(dst, 0, ret, 0, outlen);
    byte[] outlenarr = BitConverter.GetBytes(src.Length);
    Array.Copy(outlenarr, 0, ret, outlen, 4);
    return ret;
}

my code isn't competed yet (because of this error I'm not able to continue)

I dont know what Im doing wrong

thanks for help

Edited by Invicore
Link to comment
Share on other sites

If running from Scite, ensure you are running in x64 mode if calling a 64-bit dll. By default, it could be running in 32 bit mode.

Link to comment
Share on other sites

Just now, RTFC said:

If running from Scite, ensure you are running in x64 mode if calling a 64-bit dll. By default, it could be running in 32 bit mode.

yes my dll is 64Bit
I test if Im running Scite in 64bit mode with 

MsgBox(4096, '64bit.', @AutoItX64)

and yes it was running in 64bit mode

Edited by Invicore
Link to comment
Share on other sites

If the dll's calling convention is cdecl, you need to specify that in each call (append ":cdecl" to the return type).

Link to comment
Share on other sites

Just now, RTFC said:

Okay, last try: I don't see a work memory ptr being parsed in your AutoIt call.

sorry but I cant understand what you mean with I don't see a work memory ptr being parsed in your AutoIt call

there is 2 ptr in my dllcall, one is the pointer to input data that I want to compress and other is pointer that compressed data store in

Link to comment
Share on other sites

I meant this: I see three ptrs in the c# func def:

3 hours ago, Invicore said:

private static extern int lzo1x_1_compress(byte[] src, int src_len, byte[] dst, ref int dst_len, byte[] wrkmem);

and ditto in the actual call:

3 hours ago, Invicore said:

lzo1x_1_compress(src, src.Length, dst, ref outlen, _workMemory);

which references this preallocated buffer:

3 hours ago, Invicore said:

private byte[] _workMemory = new byte[16384L * 4];

AFAICT, you neither allocate nor parse a reference to this buffer in your AutoIt version of the call.

Edited by RTFC
Link to comment
Share on other sites

Based on the C# snippet that you supplied, your translation of that snippet, and the actual declaration of the function that I looked up, I see several issues and things that look odd.

This is the declaration of the function:

LZO_EXTERN(int)
lzo1x_1_compress (const lzo_bytep src,
                        lzo_uint  src_len,
                        lzo_bytep dst,
						lzo_uintp dst_len,
                        lzo_voidp wrkmem);
  1. Your AutoIt function calls lzo1c_1_compress() but the C# snippet calls lzo1x_1_compress().  Both functions exist so that leads me to wonder why you used a different function than the C# snippet?
  2. The C# snippet returns the compressed buffer.  Your AutoIt function does not.  Is $compressedBuffer a global variable that is used by the caller?  Also, you are aware that if the AutoIt DllCall is successful, $compressedBuffer is an array that contains the return code and all of the parameters, correct?.  It is not just the compressed data buffer.
  3. The function uses the cdecl calling convention.  Your DllCall is using the stdcall calling convention.
  4. In your DllCall, you are missing the 5th parameter, wrkmem, which is a pointer to a 64k byte buffer.
  5. The 4th parameter is a uint*.  In your function, you pass it a value of zero.  You need to pass it a pointer to an integer, not the value of an integer.  This alone could've caused the memory access violation error that you encountered. (rc = -1073741819 / 0xC0000005).
  6. In general, it would also help if you checked @error AND the function's return code after all DllCalls to make sure that they are successful.

Those are observations based purely at looking at what you provided.  If you had supplied an executable example that included the DLL, that reproduced the error, one wouldn't need to make observations.  They could tell you definitively what the problems are because they would've been able to test their conclusions.   By supplying just a function, without the context of how it is being called and used by the caller, means that there could be other issues.

Edited by TheXman
Link to comment
Share on other sites

@TheXman

  1. yes because I need to use lzo1c_1_compress() (looks like here is my problem... although lzo have lzo1c_1_compress() too but I don't know why its make my program crash)
  2. the C# snippet save the compressed buffer in dst 
    byte[] dst = new byte[src.Length + src.Length / 64 + 16 + 3 + 4];

    I'm also doing the same thing, I'm passing the pointer of compressed buffer to the dllcall

    Local $OutputLen = $inputSize + $inputSize / 64 + 16 + 3 + 4
    Local $tCom = DllStructCreate("BYTE[" & $OutputLen & "]")

    also for this function I don't need the return value from function itself at all

  3. yes you right

  4. you and RTFC right about that too

  5. right again this time Im passing a ptr of uint to function

  6. in my first code autoit will exit when it comes too dllcall, so I cant check @error

so at the end I changed my code

Func _lzo1cCom($handle, $buffer)
    Local $inputSize = BinaryLen($buffer)
    Local $_data = DllStructCreate("BYTE[" & $inputSize & "]")
    DllStructSetData($_data, 1, $buffer)

    Local $OutputLen = $inputSize + $inputSize / 64 + 16 + 3 + 4
    Local $tCom = DllStructCreate("BYTE[" & $OutputLen & "]")
    Local $compressedSize = DllStructCreate("UINT")
    Local $_workMemory = DllStructCreate("BYTE[" & 16384 * 4 & "]")

    DllCall($handle, "INT:cdecl", "lzo1x_1_compress", _ ;~ maybe add other lzo type here later
        "ptr", DllStructGetPtr($_data), _          ;~ src data that I want to compress
        "uint", $inputSize, _                      ;~ size of src data
        "ptr", DllStructGetPtr($tCom), _           ;~ buffer for compressed data
        "ptr", DllStructGetPtr($compressedSize), _ ;~ compressed file size
        "ptr", DllStructGetPtr($_workMemory))      ;~ working memory
    If @error Then
        Return _ErrorCheck(@error)
    EndIf
EndFunc

now its working without any problem...
but still I cant use lzo1c_1_compress() (its give me same error code as past even with new changes) maybe there is some problem with dll itself

Edited by Invicore
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...