C# PtrToStructure NullReferenceException, but VB.NET no problem.

G

Guest

Hi,

I have an application which is using a dll written in C++.
When the program go to the function below, it would raise an
NullReferenceException at the line of PtrToStructure.

public bool ServerCallBack(IntPtr log)
{
DB_T acclog = (DB_T)Marshal.PtrToStructure(log, typeof(DB_T));
}

However, if I read the log IntPtr byte by Byte , it would return part of the
correct thing.

public bool ServerCallBack(IntPtr log)
{
byte[] record = new byte[100];
IntPtr dbPoint = log;
Marshal.Copy(dbPoint,record,0,99);
char [] CharArray=
System.Text.Encoding.ASCII.GetString(record).ToCharArray();
listBox1.Items.Add(CharArray[0]); <--print correct value
}

The structure of DB_T is like this:

[StructLayout(LayoutKind.Sequential)]
public struct DB_T
{
string a;
FILETIME t;
string b;
int c;
int d;
}


Can anyone please help me how can I marshal the IntPtr type to DB_T type in
C#?
I use similar ServerCallBack function , it works fine.

Thanks,
Grace
 
W

Willy Denoyette [MVP]

C Learner said:
Hi,

I have an application which is using a dll written in C++.
When the program go to the function below, it would raise an
NullReferenceException at the line of PtrToStructure.

public bool ServerCallBack(IntPtr log)
{
DB_T acclog = (DB_T)Marshal.PtrToStructure(log, typeof(DB_T));
}

However, if I read the log IntPtr byte by Byte , it would return part of
the
correct thing.

public bool ServerCallBack(IntPtr log)
{
byte[] record = new byte[100];
IntPtr dbPoint = log;
Marshal.Copy(dbPoint,record,0,99);
char [] CharArray=
System.Text.Encoding.ASCII.GetString(record).ToCharArray();
listBox1.Items.Add(CharArray[0]); <--print correct value
}

The structure of DB_T is like this:

[StructLayout(LayoutKind.Sequential)]
public struct DB_T
{
string a;
FILETIME t;
string b;
int c;
int d;
}


Can anyone please help me how can I marshal the IntPtr type to DB_T type
in
C#?
I use similar ServerCallBack function , it works fine.

Thanks,
Grace

You have to give some more info, how does the C structure looks like, how is
your callback function declared in C, what's the character encoding used in
your C program ANSI/UNICODE ?.

Willy.
 
M

Mattias Sjögren

The structure of DB_T is like this:
[StructLayout(LayoutKind.Sequential)]
public struct DB_T
{
string a;
FILETIME t;
string b;
int c;
int d;
}

What does the corresponding native declaration look like? It's
probably the string members that are causing the exception.



Mattias
 
G

Guest

The structure of DB_T in original C code is this:
typedef struct DB_T {
char a[17];
FILETIME t
char b[17];
int c; DWORD d;
} *LPDB_T;

The Original Callback function is this:
typedef void CALLBACK RecvLogFunc(LPDB_T pA);

The Original FunctionStart in the A.dll is this:
DECL_DLL(BOOL) FunctionStart(RecvLogFunc*pCallback);

I declare the Callback function in Class Library in C# like this:
public delegate bool RecvLogCallBack(IntPtr log);

I declare the FunctionStart in the Class Library like this:
[DllImport("A.dll")]
public static extern bool FunctionStart(RecvLogCallBack pCallback);

I call the callback function like this:
private void StartServer_Click(object sender, System.EventArgs e)
{
RecvLogCallBack pCallback = new RecvLogCallBack(ServerCallBack);
if (pCallback != null)
{
if (FunctionStart(pCallback))
{
statusBar1.Text = "Started Server";
}
else statusBar1.Text = "Cannot Start Server";
}
}





The ServerCallback function is like this:
public bool ServerCallBack(IntPtr log)
{
DB_T acclog = (DB_T)Marshal.PtrToStructure(log, typeof(DB_T));
listBox1.Items.Add("1");
}

However, it comes to error in the line of PtrToStructure.
Do you have any idea?

Thanks & Regards,
Grace



Mattias Sjögren said:
The structure of DB_T is like this:

[StructLayout(LayoutKind.Sequential)]
public struct DB_T
{
string a;
FILETIME t;
string b;
int c;
int d;
}

What does the corresponding native declaration look like? It's
probably the string members that are causing the exception.



Mattias
 
G

Guest

Hi, after you guys reply, I have the clue to correct the structure and it
works fine now.
Thanks a lot.
I have modified like this and it's worked.

public struct DB_T
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)] public string a;
public FILETIME t;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)] public string b;
public int c;
public int d;
}

Thank you very much.
Grace


C Learner said:
The structure of DB_T in original C code is this:
typedef struct DB_T {
char a[17];
FILETIME t
char b[17];
int c; DWORD d;
} *LPDB_T;

The Original Callback function is this:
typedef void CALLBACK RecvLogFunc(LPDB_T pA);

The Original FunctionStart in the A.dll is this:
DECL_DLL(BOOL) FunctionStart(RecvLogFunc*pCallback);

I declare the Callback function in Class Library in C# like this:
public delegate bool RecvLogCallBack(IntPtr log);

I declare the FunctionStart in the Class Library like this:
[DllImport("A.dll")]
public static extern bool FunctionStart(RecvLogCallBack pCallback);

I call the callback function like this:
private void StartServer_Click(object sender, System.EventArgs e)
{
RecvLogCallBack pCallback = new RecvLogCallBack(ServerCallBack);
if (pCallback != null)
{
if (FunctionStart(pCallback))
{
statusBar1.Text = "Started Server";
}
else statusBar1.Text = "Cannot Start Server";
}
}





The ServerCallback function is like this:
public bool ServerCallBack(IntPtr log)
{
DB_T acclog = (DB_T)Marshal.PtrToStructure(log, typeof(DB_T));
listBox1.Items.Add("1");
}

However, it comes to error in the line of PtrToStructure.
Do you have any idea?

Thanks & Regards,
Grace



Mattias Sjögren said:
The structure of DB_T is like this:

[StructLayout(LayoutKind.Sequential)]
public struct DB_T
{
string a;
FILETIME t;
string b;
int c;
int d;
}

What does the corresponding native declaration look like? It's
probably the string members that are causing the exception.



Mattias
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top