CWS

CWS

  • NA
  • 1
  • 0

C# code from a C Library(DLL Import)

Jun 6 2007 12:46 PM
hi all. i am having trouble writing C# code that needs access to a C(not C+) DLL. first i am going to give you the C API link along with a few structs in the C header file that i will need to recreate in C#. the name of the library comes from ESRI Shapefiles and is called shapelib.dll. the link to the API is here .

DBFHandle is defined in the C header file as:

typedef struct
{
FILE *fp;
int nRecords;
int nRecordLength;
int nHeaderLength;
int nFields;
int *panFieldOffset;
int *panFieldSize;
int *panFieldDecimals;
char *pachFieldType;
char *pszHeader;
int nCurrentRecord;
int bCurrentRecordModified;
char *pszCurrentRecord;
int bNoHeader;
int bUpdated;
} DBFInfo;

typedef DBFInfo * DBFHandle;
//also an enum declaration

typedef enum {
FTString,
FTInteger,
FTDouble,
FTLogical,
FTInvalid
} DBFFieldType;

here is now my C# code along with my main function:

using System;
using System.Runtime.InteropServices;
using System.Text;
namespace shapeFileReader
{
[StructLayout(LayoutKind.Sequential)]
struct DBFInfo
{
public IntPtr fp;
public int nRecords;
public int nRecordLength;
public int nHeaderLength;
public int nFields;
public IntPtr panFieldOffset;
public IntPtr panFieldSize;
public IntPtr panFieldDecimals;
public string pachFieldType;
public string pszHeader;
public int nCurrentRecord;
public int bCurrentRecordModified;
public string pszCurrentRecord;
public int bNoHeader;
public int nBufSize;
};

class Class1
{

[DllImport("shapelib.dll", EntryPoint = "DBFOpen", ExactSpelling=true, CallingConvention=CallingConvention.Cdecl)]
private static extern IntPtr internalDBFOpen(string pszShapeFile, string pszAccess);

public static DBFInfo DBFOpen(string pszShapeFile, string pszAccess)
{
IntPtr ptr = internalDBFOpen(pszShapeFile, pszAccess);
return (DBFInfo)Marshal.PtrToStructure(ptr, typeof(DBFInfo));
}

static void Main(string[] args)
{
DBFInfo myHandle;
myHandle = DBFOpen("BG2k_clip.dbf", "rb");
Console.WriteLine("reading shapefile parser");
}
}
}

it compiles fine but at runtime i get a NULL Exception error when i try to return the pointer ptr back to main. when going through the debugger ptr is indeed 0(NULL) but i have no idea why. i have already done a C++ version of this and i was able to read a file just fine with no errors whatsoever so i am pretty sure my calling convention is correct.
the error that i get is:

Additional information: Object reference not set to an instance of an object.

The program '[3392] shapeFileReader.exe' has exited with code 0 (0x0).

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at shapeFileReader.Class1.DBFOpen(String pszShapeFile, String pszAccess) in c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs:line 37

at shapeFileReader.Class1.Main(String[] args) in c:\apps\microsoft visual studio .net 2003\vc#\csharpprojects\shapefilereader\class1.cs:line 42

My entry point of DBFOpen is defined in the shapelib.DEF file so i double checked that. here are 4 screenshots in order in the debugger so you can see what is happening.

i would love to have help if anyone has a clue as to what is going on. at first i was going to try to do a C++/CLI wrapper but i am using VS 2003.

step 1
step 2
step 3
step 4