Uncompressing using unrar.dll P/Invoke what do I do wrong?

  • Thread starter Thread starter Oliver
  • Start date Start date
O

Oliver

Hello !

I am trying to get the unrar.dll working in C#... it seems that I correctly
imported the functions as the first 2 function work without problem
(RAROpenArchive & RARGetDLLVersion)... however always if I want to execute
the RARReadHeader Function I get "Object reference not set to an instance
of an object"

What do I wrong, I used the unrar.dll documentation and I really dont find
any mistakes but why do I always get this error message and why do i only
get it by calling the function RARReadHeader?

Thanks in advance,
Oliver

------------------------- Code -------------------------------


using System;
using System.Runtime.InteropServices;

namespace Unrar
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
public const int ERAR_END_ARCHIVE = 10;
public const int ERAR_NO_MEMORY = 11;
public const int ERAR_BAD_DATA = 12;
public const int ERAR_BAD_ARCHIVE = 13;
public const int ERAR_UNKNOWN_FORMAT = 14;
public const int ERAR_EOPEN = 15;
public const int ERAR_ECREATE = 16;
public const int ERAR_ECLOSE = 17;
public const int ERAR_EREAD = 18;
public const int ERAR_EWRITE = 19;
public const int ERAR_SMALL_BUF = 20;

public const int RAR_OM_LIST = 0;
public const int RAR_OM_EXTRACT = 1;

public const int RAR_SKIP = 0;
public const int RAR_TEST = 1;
public const int RAR_EXTRACT = 2;

public const int RAR_VOL_ASK = 0;
public const int RAR_VOL_NOTIFY = 1;

public enum RarOperations
{
OP_EXTRACT = 0,
OP_TEST = 1,
OP_LIST = 2
}

public struct RARHeaderData
{
public string ArcName;
public string FileName;
public uint Flags;
public uint PackSize;
public uint UnpSize;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
}

public struct RAROpenArchiveData
{
public string ArcName;
public uint OpenMode;
public uint OpenResult;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
}

public struct RAROpenArchiveDataEx
{
public string ArcName;
public string ArcNameW;
public uint OpenMode;
public uint OpenResult;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public uint Flags;
public uint Reserved;
}
public struct RARHeaderDataEx
{
public string ArcName;
public string ArcNameW;
public string FileName;
public string FileNameW;
public uint Flags;
public uint PackSize;
public uint PackSizeHigh;
public uint UnpSize;
public uint UnpSizeHigh;
public uint HostOS;
public uint FileCRC;
public uint FileTime;
public uint UnpVer;
public uint Method;
public uint FileAttr;
public string CmtBuf;
public uint CmtBufSize;
public uint CmtSize;
public uint CmtState;
public uint Reserved;
};


[DllImportAttribute("unrar.dll")]
public static extern IntPtr RAROpenArchive (ref
RAROpenArchiveData ArchiveData);
[DllImportAttribute("unrar.dll")]
public static extern int RARCloseArchive(IntPtr hArcData);
[DllImportAttribute("unrar.dll")]
public static extern int RARReadHeader (IntPtr hArcData, ref
RARHeaderData HeaderData);
[DllImportAttribute("unrar.dll")]
public static extern IntPtr RAROpenArchiveEx(ref
RAROpenArchiveDataEx ArchiveData);
[DllImportAttribute("unrar.dll")]
public static extern int RARReadHeaderEx(IntPtr hArcData, ref
RARHeaderDataEx HeaderData);
[DllImportAttribute("unrar.dll")]
public static extern int RARProcessFile(IntPtr hArcData, int
Operation, string DestPath, string DestName);
[DllImportAttribute("unrar.dll")]
public static extern int RARGetDllVersion();


static void Main(string[] args)
{
IntPtr lHandle;
int iStatus;
RARHeaderData uHeader=new RARHeaderData();
RAROpenArchiveData uRAR=new RAROpenArchiveData();

uRAR.ArcName = "D:\\adddas.rar";
uRAR.CmtBuf = string.Empty.PadLeft(16384,' ');
uRAR.CmtBufSize = 16384;
uRAR.OpenMode=RAR_OM_LIST;

Console.WriteLine("DLL Version: {0}",RARGetDllVersion());

lHandle = RAROpenArchive(ref uRAR);
Console.WriteLine("OpenResult: {0}",uRAR.OpenResult);
Console.WriteLine("CmtState: {0}",uRAR.CmtState);


iStatus=RARReadHeader(lHandle, ref uHeader);
Console.WriteLine("Status: {0}",iStatus);

iStatus = RARCloseArchive(lHandle);
Console.WriteLine("Status: {0}",iStatus);
}
}
}
 
Hello !

I am trying to get the unrar.dll working in C#... it seems that
I correctly imported the functions as the first 2 function work
without problem (RAROpenArchive & RARGetDLLVersion)... however
always if I want to execute the RARReadHeader Function I get
"Object reference not set to an instance of an object"

What do I wrong, I used the unrar.dll documentation and I really
dont find any mistakes but why do I always get this error
message and why do i only get it by calling the function
RARReadHeader?

Oliver,

The RARHeaderData structure has two string parameters which are
supposed to represent fixed length arrays of characters (e.g. "char
arcName[260];" in C). When using P/Invoke, a string instead of a
character array is typically used. However, the fixed-length nature
of the string must be explicitly stated using the MarshalAs
attribute:

public struct RARHeaderData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ArcName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string FileName;
...
}

I added these two attributes and ran your code. It seemed to work
OK.

Hope this helps.

Chris.
 
Hi Chris!!!

Thank you very much for you help! That was exactly which was missing.
Didn't know how I could make them fixed size since string ArcName[260] or
similar didnt work!

So thanks for taking the time to test it and give me the correct answer. I
really appreciate that! I sat 4 hours and searched the internet but didnt
find any answer to this :)

Thanks,
Oliver
 
Back
Top