Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Error: Calling C++ dll function in C#

Error: Calling C++ dll function in C#

Scheduled Pinned Locked Moved C#
helpcsharpc++databaseperformance
22 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Lost User

    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.

    J Offline
    J Offline
    J4amieC
    wrote on last edited by
    #12

    The OP has laid them out alphabetically in c#, im pretty sure this will be the issue, non?

    L 1 Reply Last reply
    0
    • L Lost User

      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.

      T Offline
      T Offline
      taibc
      wrote on last edited by
      #13

      I only convert the field type: unsigned char * (in C) into byte[] (in C#)

      L 1 Reply Last reply
      0
      • T taibc

        I only convert the field type: unsigned char * (in C) into byte[] (in C#)

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #14

        Yes but you have moved the elements into different positions within the structure. How can that work?

        One of these days I'm going to think of a really clever signature.

        1 Reply Last reply
        0
        • J J4amieC

          The OP has laid them out alphabetically in c#, im pretty sure this will be the issue, non?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #15

          True; I did not check that originally, it never occurred to me that anyone would think of doing such a thing. :doh:

          One of these days I'm going to think of a really clever signature.

          1 Reply Last reply
          0
          • T taibc

            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")]
            p

            B Offline
            B Offline
            BobJanova
            wrote on last edited by
            #16

            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.
            T 2 Replies Last reply
            0
            • B BobJanova

              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.
              T Offline
              T Offline
              taibc
              wrote on last edited by
              #17

              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 !

              T 1 Reply Last reply
              0
              • T taibc

                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 !

                T Offline
                T Offline
                taibc
                wrote on last edited by
                #18

                Hi, I found out the reason of the error. After changing the order of fields in Class and using "IntPrt" instead "byte[]" in C# (for char * in C). I can run without error. Thank you very much !

                1 Reply Last reply
                0
                • T taibc

                  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")]
                  p

                  T Offline
                  T Offline
                  taibc
                  wrote on last edited by
                  #19

                  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;
                  }
                  
                  M 1 Reply Last reply
                  0
                  • T taibc

                    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;
                    }
                    
                    M Offline
                    M Offline
                    mphill4744
                    wrote on last edited by
                    #20

                    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

                    T 1 Reply Last reply
                    0
                    • M mphill4744

                      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

                      T Offline
                      T Offline
                      taibc
                      wrote on last edited by
                      #21

                      Hi. I got the answer from msdn forum: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/2b6c3bc0-1c78-4d50-97d6-3100326aea09/#caa9aa68-8e57-4235-be16-29603e41f3f0[^] But, I am getting another error.

                      1 Reply Last reply
                      0
                      • B BobJanova

                        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.
                        T Offline
                        T Offline
                        taibc
                        wrote on last edited by
                        #22

                        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 ?

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups