DllImport and Structures - spidermonkey

T

Thomas

Hello all

Having trouble with getting Error Information from spidermonkey. How would
one convert a C structure to CSharp?

struct JSErrorReport {
const char *filename; // source file name, URL, etc., or null
uintN lineno; // source line number
const char *linebuf; // offending source line without
final \n
const char *tokenptr; // pointer to error token in linebuf
const jschar *uclinebuf; // unicode (original) line buffer
const jschar *uctokenptr; // unicode (original) token pointer
uintN flags; // error/warning, etc.
uintN errorNumber; // the error number, e.g. see
js.msg
const jschar *ucmessage; // the (default) error message
const jschar **messageArgs; // arguments for the error message
}

as well as a C type callback function:
ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)

I've been working on this thing for a week and only got to the point where I
can get it to call ErrorReporter, but it returns gibberish. - Sample below.
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
public delegate void CallBackPtr(IntPtr cx, IntPtr message, JS.JSErrorReport
report);
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct JSErrorReport
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string filename;
public UInt16 lineno;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string linebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string tokenptr;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uclinebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uctokenptr;
public UInt16 flags;
public UInt16 errorNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ucmessage;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string messageArgs;
};
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
Any type of help or direction on this thing will finally let me sleep at
night.

Thanks
Thomas
 
N

Nicholas Paldino [.NET/C# MVP]

Thomas,

Well, you aren't including all of the information that is needed. For
example, what is a JSContext, jschar, uintN?

Regardless, the one thing I can tell automatically that you are doing
wrong is that you are declaring your string types with this attribute:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]

The thing is, your structure declaration has pointers to those strings,
they aren't embedded in the structure. You need to declare these as IntPtrs
and marshal the strings yourself, or (and I am not positive that this will
work) change it to a string (without the ByValTStr modifier), both of which
should marshal it as a pointer, which is what your structure declares.

The same goes for the jschar types, if they are just typedefs for
characters.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Thomas said:
Hello all

Having trouble with getting Error Information from spidermonkey. How would
one convert a C structure to CSharp?

struct JSErrorReport {
const char *filename; // source file name, URL, etc., or
null
uintN lineno; // source line number
const char *linebuf; // offending source line without
final \n
const char *tokenptr; // pointer to error token in linebuf
const jschar *uclinebuf; // unicode (original) line buffer
const jschar *uctokenptr; // unicode (original) token pointer
uintN flags; // error/warning, etc.
uintN errorNumber; // the error number, e.g. see
js.msg
const jschar *ucmessage; // the (default) error message
const jschar **messageArgs; // arguments for the error message
}

as well as a C type callback function:
ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)

I've been working on this thing for a week and only got to the point where
I can get it to call ErrorReporter, but it returns gibberish. - Sample
below.
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
public delegate void CallBackPtr(IntPtr cx, IntPtr message,
JS.JSErrorReport report);
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct JSErrorReport
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string filename;
public UInt16 lineno;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string linebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string tokenptr;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uclinebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uctokenptr;
public UInt16 flags;
public UInt16 errorNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ucmessage;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string messageArgs;
};
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
Any type of help or direction on this thing will finally let me sleep at
night.

Thanks
Thomas
 
T

Thomas

Nicholas

JSContext was another structure, but not used. jschar, uintN Changed. And
changed struct to class:

[StructLayout(LayoutKind.Explicit)]
public class JSErrorReport
{
[FieldOffset(0)] public string filename;
[FieldOffset(4)] public uint lineno;
[FieldOffset(8)] public string linebuf;
[FieldOffset(12)] public string tokenptr;
[FieldOffset(16)] public ushort uclinebuf;
[FieldOffset(20)] public ushort uctokenptr;
[FieldOffset(24)] public uint flags;
[FieldOffset(28)] public uint errorNumber;
[FieldOffset(32)] public ushort ucmessage;
[FieldOffset(36)] public ushort messageArgs;
};

public static void ErrorReporter(IntPtr cx, string message, JSErrorReport
report)
{
string tmp = string.Format("\r\n\tAt line {0:d4}", report.lineno + 1);
Program.str = message + tmp;
}

Now I can get the Error Message and line number.

Thomas

Nicholas Paldino said:
Thomas,

Well, you aren't including all of the information that is needed. For
example, what is a JSContext, jschar, uintN?

Regardless, the one thing I can tell automatically that you are doing
wrong is that you are declaring your string types with this attribute:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]

The thing is, your structure declaration has pointers to those strings,
they aren't embedded in the structure. You need to declare these as
IntPtrs and marshal the strings yourself, or (and I am not positive that
this will work) change it to a string (without the ByValTStr modifier),
both of which should marshal it as a pointer, which is what your structure
declares.

The same goes for the jschar types, if they are just typedefs for
characters.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Thomas said:
Hello all

Having trouble with getting Error Information from spidermonkey. How
would one convert a C structure to CSharp?

struct JSErrorReport {
const char *filename; // source file name, URL, etc., or
null
uintN lineno; // source line number
const char *linebuf; // offending source line without
final \n
const char *tokenptr; // pointer to error token in linebuf
const jschar *uclinebuf; // unicode (original) line buffer
const jschar *uctokenptr; // unicode (original) token pointer
uintN flags; // error/warning, etc.
uintN errorNumber; // the error number, e.g. see
js.msg
const jschar *ucmessage; // the (default) error message
const jschar **messageArgs; // arguments for the error message
}

as well as a C type callback function:
ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)

I've been working on this thing for a week and only got to the point
where I can get it to call ErrorReporter, but it returns gibberish. -
Sample below.
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
public delegate void CallBackPtr(IntPtr cx, IntPtr message,
JS.JSErrorReport report);
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct JSErrorReport
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string filename;
public UInt16 lineno;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string linebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string tokenptr;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uclinebuf;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string uctokenptr;
public UInt16 flags;
public UInt16 errorNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string ucmessage;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string messageArgs;
};
<*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*><*>
Any type of help or direction on this thing will finally let me sleep at
night.

Thanks
Thomas
 

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