Error: Calling C++ dll function in C#
-
How I can trace the error through source codes while I am using dll file ? and I think the source codes don't have error, because I still can use it in Visual C++, but I got the error while trying in C#
-
I have just looked again at the layout of your C++ and C# structures; why are they different?
One of these days I'm going to think of a really clever signature.
-
I have just looked again at the layout of your C++ and C# structures; why are they different?
One of these days I'm going to think of a really clever signature.
-
The OP has laid them out alphabetically in c#, im pretty sure this will be the issue, non?
-
Hi, I am trying to use functions in C++ dll from C#, but I got an error: "attempt to read or write protected memory. This is often indication that other memory is corrupt" Anyone know how to fix ? Here is C++ functions:
typedef void *DGNHandle;
__declspec(dllexport) DGNHandle CPL_DLL DGNOpen( const char *, int );
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle )Here is structure in C++:
typedef struct {
int offset;
int size;int element\_id; /\*!< Element number (zero based) \*/ int stype; /\*!< Structure type: (DGNST\_\*) \*/ int level; /\*!< Element Level: 0-63 \*/ int type; /\*!< Element type (DGNT\_) \*/ int complex; /\*!< Is element complex? \*/ int deleted; /\*!< Is element deleted? \*/ int graphic\_group; /\*!< Graphic group number \*/ int properties; /\*!< Properties: ORing of DGNPF\_ flags \*/ int color; /\*!< Color index (0-255) \*/ int weight; /\*!< Line Weight (0-31) \*/ int style; /\*!< Line Style: One of DGNS\_\* values \*/ int attr\_bytes; /\*!< Bytes of attribute data, usually zero. \*/ unsigned char \*attr\_data; /\*!< Raw attribute data \*/ int raw\_bytes; /\*!< Bytes of raw data, usually zero. \*/ unsigned char \*raw\_data; /\*!< All raw element data including header. \*/
} DGNElemCore;
And below converted codes are in C#:
[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
public int attr_bytes;
public byte[] attr_data;
public int color;
public int complex;
public int deleted;
public int element_id;
public int graphic_group;
public int level;
public int offset;
public int properties;
public int raw_bytes;
public byte[] raw_data;
public int size;
public int style;
public int stype;
public int type;
public int weight;}
[DllImport("DgnLib.dll", EntryPoint = "DGNOpen")]
public static extern IntPtr DGNOpen(string fileName, int bUpdate);
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
pThis isn't my area but:
- Defining the fields in the struct in a different order definitely won't work. You need to declare in the same order (hopefully the reason for this is obvious).
- You've defined it as a class in C#, not a struct. I think you need it to be a struct, even though it's a pointer type declaration in C++. You might even need to declare it IntPtr and use Marshal methods to make a struct out of it.
- What is DGNHandle? That C++ function definition isn't valid unless it's a macro.
-
This isn't my area but:
- Defining the fields in the struct in a different order definitely won't work. You need to declare in the same order (hopefully the reason for this is obvious).
- You've defined it as a class in C#, not a struct. I think you need it to be a struct, even though it's a pointer type declaration in C++. You might even need to declare it IntPtr and use Marshal methods to make a struct out of it.
- What is DGNHandle? That C++ function definition isn't valid unless it's a macro.
Thanks BobJanova and Richard MacCutchan very much. I changed the order of fields and using "struct" instead of "class" in C#. DGNHandle is "Opaque handle representing DGN file, used with DGN API" Now, I got another error: Exception of type 'System.ExecutionEngineException' was thrown. Please see my detail codes:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);public static DGNElemCore ReadElement(IntPtr DGNHandle) { DGNElemCore element = new DGNElemCore (); IntPtr itr = DGNReadElement(DGNHandle); element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore)); **// throw the exception** return element; }
I am wondering: Can I convert a structure pointer (DGNElemCore *) in C to IntPtr (in C#), then use Marshal to get DGNElemCore. The function in C is:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
Thank you very much !
-
Thanks BobJanova and Richard MacCutchan very much. I changed the order of fields and using "struct" instead of "class" in C#. DGNHandle is "Opaque handle representing DGN file, used with DGN API" Now, I got another error: Exception of type 'System.ExecutionEngineException' was thrown. Please see my detail codes:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);public static DGNElemCore ReadElement(IntPtr DGNHandle) { DGNElemCore element = new DGNElemCore (); IntPtr itr = DGNReadElement(DGNHandle); element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore)); **// throw the exception** return element; }
I am wondering: Can I convert a structure pointer (DGNElemCore *) in C to IntPtr (in C#), then use Marshal to get DGNElemCore. The function in C is:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
Thank you very much !
-
Hi, I am trying to use functions in C++ dll from C#, but I got an error: "attempt to read or write protected memory. This is often indication that other memory is corrupt" Anyone know how to fix ? Here is C++ functions:
typedef void *DGNHandle;
__declspec(dllexport) DGNHandle CPL_DLL DGNOpen( const char *, int );
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle )Here is structure in C++:
typedef struct {
int offset;
int size;int element\_id; /\*!< Element number (zero based) \*/ int stype; /\*!< Structure type: (DGNST\_\*) \*/ int level; /\*!< Element Level: 0-63 \*/ int type; /\*!< Element type (DGNT\_) \*/ int complex; /\*!< Is element complex? \*/ int deleted; /\*!< Is element deleted? \*/ int graphic\_group; /\*!< Graphic group number \*/ int properties; /\*!< Properties: ORing of DGNPF\_ flags \*/ int color; /\*!< Color index (0-255) \*/ int weight; /\*!< Line Weight (0-31) \*/ int style; /\*!< Line Style: One of DGNS\_\* values \*/ int attr\_bytes; /\*!< Bytes of attribute data, usually zero. \*/ unsigned char \*attr\_data; /\*!< Raw attribute data \*/ int raw\_bytes; /\*!< Bytes of raw data, usually zero. \*/ unsigned char \*raw\_data; /\*!< All raw element data including header. \*/
} DGNElemCore;
And below converted codes are in C#:
[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
public int attr_bytes;
public byte[] attr_data;
public int color;
public int complex;
public int deleted;
public int element_id;
public int graphic_group;
public int level;
public int offset;
public int properties;
public int raw_bytes;
public byte[] raw_data;
public int size;
public int style;
public int stype;
public int type;
public int weight;}
[DllImport("DgnLib.dll", EntryPoint = "DGNOpen")]
public static extern IntPtr DGNOpen(string fileName, int bUpdate);
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
pI am getting another error when casting between two structs in C#: I have the function in C:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
This function will read a file and return a pointer to either DGNElemCore or DGNElemText, and I can use casting between them. But, when I convert codes into C# as below, I can't cast types of these structs:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);
public static DGNElemCore ReadElement(IntPtr DGNHandle)
{
DGNElemCore element = new DGNElemCore ();
IntPtr itr = DGNReadElement(DGNHandle);
MessageBox.Show(itr.GetType ().ToString ());element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore)); return element; }
And the codes for testing:
DGNElemCore element = new DGNElemCore();
element = DgnFile.ReadElement(DGNHandle);while (element != null)
{
if (element.type == 17 ) // Element is a DGNElemText
{
DGNElemText txtElement = new DGNElemText();
txtElement = (DGNElemText)element; **// throw error: Unable to cast object of type DgnLib.DGNElemCore to type DgnLib.DGNElemText**...... // More codes }
}
Structs in C#:
[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
public int offset;
public int size;
public int element_id;
public int stype;
public int level;
public int type;
public int complex;
public int deleted;
public int graphic_group;
public int properties;
public int color;
public int weight;
public int style;
public int attr_bytes;
public IntPtr attr_data;
public int raw_bytes;
public IntPtr raw_data;}
[StructLayout (LayoutKind.Sequential)]
public class DGNElemText : DGNElemCore
{
// Fields
DGNElemCore core;public int font\_id; public int justification; public double length\_mult; public double height\_mult; public double rotation; public DGNPoint origin; public string text; }
-
I am getting another error when casting between two structs in C#: I have the function in C:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
This function will read a file and return a pointer to either DGNElemCore or DGNElemText, and I can use casting between them. But, when I convert codes into C# as below, I can't cast types of these structs:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);
public static DGNElemCore ReadElement(IntPtr DGNHandle)
{
DGNElemCore element = new DGNElemCore ();
IntPtr itr = DGNReadElement(DGNHandle);
MessageBox.Show(itr.GetType ().ToString ());element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore)); return element; }
And the codes for testing:
DGNElemCore element = new DGNElemCore();
element = DgnFile.ReadElement(DGNHandle);while (element != null)
{
if (element.type == 17 ) // Element is a DGNElemText
{
DGNElemText txtElement = new DGNElemText();
txtElement = (DGNElemText)element; **// throw error: Unable to cast object of type DgnLib.DGNElemCore to type DgnLib.DGNElemText**...... // More codes }
}
Structs in C#:
[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
public int offset;
public int size;
public int element_id;
public int stype;
public int level;
public int type;
public int complex;
public int deleted;
public int graphic_group;
public int properties;
public int color;
public int weight;
public int style;
public int attr_bytes;
public IntPtr attr_data;
public int raw_bytes;
public IntPtr raw_data;}
[StructLayout (LayoutKind.Sequential)]
public class DGNElemText : DGNElemCore
{
// Fields
DGNElemCore core;public int font\_id; public int justification; public double length\_mult; public double height\_mult; public double rotation; public DGNPoint origin; public string text; }
I am not sure if you are a member of the Bentley communities but there is a specific programming forum that can address these questions with the developers and other users. I am just starting to learn C# and use both CP and Bentley sites for help. http://communities.bentley.com/products/microstation/microstation_programming/w/microstation_v8i_programming_wiki/default.aspx[^]
I'll tell you what, then. Why don't you call me some time when you have no class? - Thornton Melon
-
I am not sure if you are a member of the Bentley communities but there is a specific programming forum that can address these questions with the developers and other users. I am just starting to learn C# and use both CP and Bentley sites for help. http://communities.bentley.com/products/microstation/microstation_programming/w/microstation_v8i_programming_wiki/default.aspx[^]
I'll tell you what, then. Why don't you call me some time when you have no class? - Thornton Melon
-
This isn't my area but:
- Defining the fields in the struct in a different order definitely won't work. You need to declare in the same order (hopefully the reason for this is obvious).
- You've defined it as a class in C#, not a struct. I think you need it to be a struct, even though it's a pointer type declaration in C++. You might even need to declare it IntPtr and use Marshal methods to make a struct out of it.
- What is DGNHandle? That C++ function definition isn't valid unless it's a macro.
Hi BobJanova, I resolved that error as your sugesstion. However, I am getting another error while trying to get the text value of a char array in C. For example: I have a struct in C that inclue a char array like below:
struct DGNElemText
{
.....char text[1]; /*!< Actual text (length varies, \0 terminated*/
....
}And the converted codes in C#:
[StructLayout(LayoutKind.Sequential)]
public class DGNElemText
{
.....IntPtr text;
}And I got the text value by using Marshal.PtrToStringAnsi(...). But I always received an empty text value. It is not expected value such as: "Hello", "abc123",... I still got the same value when trying to use the another way:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
public string text;Do you know why ?