OCX(COM) Interop...Passing pointer of structure to function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?TWluZ3lp?=

    OCX(COM) Interop...Passing pointer of structure to function

    Hi,

    I have the following question regarding communicating with a OCX control
    using C#. Idon't have access to the ocx code, so my c# code is actually mimic
    the behavior of C++ counterparts. Basically, I have problem passing a
    structure to a function.

    Here is the C++ part code:

    //*************** *************** **********
    typedef struct
    {
    char TypeID;
    char UserName[20];
    char Password[20];
    char UrlAddress[255];
    int iStreamChannel;
    bool bDirectDrawMode ;
    }CONNECT_DATA;

    CONNECT_DATA m_ConnectData;

    // after initializing m_ConnectData

    int ret= InitConnectData ((PBYTE)&m_Conn ectData);

    //*************** *************** **********

    In C# when I drop this active control to my app, the interface for the
    function
    InitConnectData has be given as follows

    InitConnectData (ref byte)

    So the following is what I did in the C# part.

    //*************** *************** **********

    [StructLayout(La youtKind.Sequen tial,CharSet=Ch arSet.Ansi,Pack =8)]
    public unsafe struct CONNECT_DATA
    {
    public byte TypeID;

    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
    public string UserName;

    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
    public string Password;

    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 255)]
    public string UrlAddress;

    public int iStreamChannel;
    public bool bDirectDrawMode ;

    }

    CONNECT_DATA connect_data = new CONNECT_DATA();

    // After initializing all the fields

    IntPtr pnt = Marshal.AllocCo TaskMem(Marshal .SizeOf(connect _data));
    try
    {
    Marshal.Structu reToPtr(connect _data, pnt, false);
    byte[] buffer = new byte[Marshal.SizeOf( connect_data)];
    Marshal.Copy(pn t, buffer, 0, Marshal.SizeOf( connect_data));
    int ret = axNetworkCamera Link2.InitConne ctData(ref buffer[0]);
    }
    //*************** *************** **********

    But it seems that the function never gets the structure right, for it always
    gives the wrong return value.

    I tried to "Tlbimp" the original DLL, change the IL code so that the
    "InitConnectDat a(uint8&)" becames "InitConnectDat a(native int)", and in C#
    the interface becames "InitConnectDat a(System.IntPtr )", but error occurs,
    stating that

    "System.Runtime .InteropService s.COMException
    (0x80020005): Type mismatch. at
    System.RuntimeT ype.ForwardCall ToInvokeMember( String memberName, BindingFlags
    flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)"

    I guess it is because uint8 is 8 bit and native int is 32 bit...I really
    don't know
    what to do now, and I think I must do something wrong...Please help, thanks!

  • G Himangi

    #2
    Re: OCX(COM) Interop...Passi ng pointer of structure to function

    Dont know about the actual call but I can see a few problems with your
    structure definition :

    1. The UserName,passwo rd and address are defined as ByValTStr (means Ansi or
    Uni depending on platform) when in fact they are defined as ANSI in the
    original structure.

    2. The bDirectDrawMode is defined as bool (which marshals to 4 bytes) but
    the origianl structure defines it as smallcase bool which in C++ I think
    occupies 1 byte.

    ---------
    - G Himangi, LogicNP Software http://www.ssware.com
    Shell MegaPack: GUI Controls For Drop-In Windows Explorer like File/Folder
    Browsing Functionality (.Net & ActiveX Editions).
    EZNamespaceExte nsions: Develop namespace extensions rapidly in .Net and
    MFC/ATL/C++
    EZShellExtensio ns: Develop all shell extensions,expl orer bars and BHOs
    rapidly in .Net & MFC/ATL/C++
    ---------

    "Mingyi" <Mingyi@discuss ions.microsoft. comwrote in message
    news:4C4CAA20-EB0D-4D78-8C1D-FE1832B11C99@mi crosoft.com...
    Hi,
    >
    I have the following question regarding communicating with a OCX control
    using C#. Idon't have access to the ocx code, so my c# code is actually
    mimic
    the behavior of C++ counterparts. Basically, I have problem passing a
    structure to a function.
    >
    Here is the C++ part code:
    >
    //*************** *************** **********
    typedef struct
    {
    char TypeID;
    char UserName[20];
    char Password[20];
    char UrlAddress[255];
    int iStreamChannel;
    bool bDirectDrawMode ;
    }CONNECT_DATA;
    >
    CONNECT_DATA m_ConnectData;
    >
    // after initializing m_ConnectData
    >
    int ret= InitConnectData ((PBYTE)&m_Conn ectData);
    >
    //*************** *************** **********
    >
    In C# when I drop this active control to my app, the interface for the
    function
    InitConnectData has be given as follows
    >
    InitConnectData (ref byte)
    >
    So the following is what I did in the C# part.
    >
    //*************** *************** **********
    >
    [StructLayout(La youtKind.Sequen tial,CharSet=Ch arSet.Ansi,Pack =8)]
    public unsafe struct CONNECT_DATA
    {
    public byte TypeID;
    >
    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
    public string UserName;
    >
    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
    public string Password;
    >
    [MarshalAs(Unman agedType.ByValT Str, SizeConst = 255)]
    public string UrlAddress;
    >
    public int iStreamChannel;
    public bool bDirectDrawMode ;
    >
    }
    >
    CONNECT_DATA connect_data = new CONNECT_DATA();
    >
    // After initializing all the fields
    >
    IntPtr pnt = Marshal.AllocCo TaskMem(Marshal .SizeOf(connect _data));
    try
    {
    Marshal.Structu reToPtr(connect _data, pnt, false);
    byte[] buffer = new byte[Marshal.SizeOf( connect_data)];
    Marshal.Copy(pn t, buffer, 0, Marshal.SizeOf( connect_data));
    int ret = axNetworkCamera Link2.InitConne ctData(ref
    buffer[0]);
    }
    //*************** *************** **********
    >
    But it seems that the function never gets the structure right, for it
    always
    gives the wrong return value.
    >
    I tried to "Tlbimp" the original DLL, change the IL code so that the
    "InitConnectDat a(uint8&)" becames "InitConnectDat a(native int)", and in C#
    the interface becames "InitConnectDat a(System.IntPtr )", but error occurs,
    stating that
    >
    "System.Runtime .InteropService s.COMException
    (0x80020005): Type mismatch. at
    System.RuntimeT ype.ForwardCall ToInvokeMember( String memberName,
    BindingFlags
    flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)"
    >
    I guess it is because uint8 is 8 bit and native int is 32 bit...I really
    don't know
    what to do now, and I think I must do something wrong...Please help,
    thanks!
    >

    Comment

    • =?Utf-8?B?TWluZ3lp?=

      #3
      Re: OCX(COM) Interop...Passi ng pointer of structure to function


      Hi,

      I think the first problem is solved by the declaration
      "CharSet=CharSe t.Ansi" (I think..)

      For the second one, I used to marshall the bool to 1 byte counterpart, but
      the problem persists..

      Thanks for the reply anyway.


      "G Himangi" wrote:
      Dont know about the actual call but I can see a few problems with your
      structure definition :
      >
      1. The UserName,passwo rd and address are defined as ByValTStr (means Ansi or
      Uni depending on platform) when in fact they are defined as ANSI in the
      original structure.
      >
      2. The bDirectDrawMode is defined as bool (which marshals to 4 bytes) but
      the origianl structure defines it as smallcase bool which in C++ I think
      occupies 1 byte.
      >
      ---------
      - G Himangi, LogicNP Software http://www.ssware.com
      Shell MegaPack: GUI Controls For Drop-In Windows Explorer like File/Folder
      Browsing Functionality (.Net & ActiveX Editions).
      EZNamespaceExte nsions: Develop namespace extensions rapidly in .Net and
      MFC/ATL/C++
      EZShellExtensio ns: Develop all shell extensions,expl orer bars and BHOs
      rapidly in .Net & MFC/ATL/C++
      ---------
      >
      "Mingyi" <Mingyi@discuss ions.microsoft. comwrote in message
      news:4C4CAA20-EB0D-4D78-8C1D-FE1832B11C99@mi crosoft.com...
      Hi,

      I have the following question regarding communicating with a OCX control
      using C#. Idon't have access to the ocx code, so my c# code is actually
      mimic
      the behavior of C++ counterparts. Basically, I have problem passing a
      structure to a function.

      Here is the C++ part code:

      //*************** *************** **********
      typedef struct
      {
      char TypeID;
      char UserName[20];
      char Password[20];
      char UrlAddress[255];
      int iStreamChannel;
      bool bDirectDrawMode ;
      }CONNECT_DATA;

      CONNECT_DATA m_ConnectData;

      // after initializing m_ConnectData

      int ret= InitConnectData ((PBYTE)&m_Conn ectData);

      //*************** *************** **********

      In C# when I drop this active control to my app, the interface for the
      function
      InitConnectData has be given as follows

      InitConnectData (ref byte)

      So the following is what I did in the C# part.

      //*************** *************** **********

      [StructLayout(La youtKind.Sequen tial,CharSet=Ch arSet.Ansi,Pack =8)]
      public unsafe struct CONNECT_DATA
      {
      public byte TypeID;

      [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
      public string UserName;

      [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
      public string Password;

      [MarshalAs(Unman agedType.ByValT Str, SizeConst = 255)]
      public string UrlAddress;

      public int iStreamChannel;
      public bool bDirectDrawMode ;

      }

      CONNECT_DATA connect_data = new CONNECT_DATA();

      // After initializing all the fields

      IntPtr pnt = Marshal.AllocCo TaskMem(Marshal .SizeOf(connect _data));
      try
      {
      Marshal.Structu reToPtr(connect _data, pnt, false);
      byte[] buffer = new byte[Marshal.SizeOf( connect_data)];
      Marshal.Copy(pn t, buffer, 0, Marshal.SizeOf( connect_data));
      int ret = axNetworkCamera Link2.InitConne ctData(ref
      buffer[0]);
      }
      //*************** *************** **********

      But it seems that the function never gets the structure right, for it
      always
      gives the wrong return value.

      I tried to "Tlbimp" the original DLL, change the IL code so that the
      "InitConnectDat a(uint8&)" becames "InitConnectDat a(native int)", and in C#
      the interface becames "InitConnectDat a(System.IntPtr )", but error occurs,
      stating that

      "System.Runtime .InteropService s.COMException
      (0x80020005): Type mismatch. at
      System.RuntimeT ype.ForwardCall ToInvokeMember( String memberName,
      BindingFlags
      flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)"

      I guess it is because uint8 is 8 bit and native int is 32 bit...I really
      don't know
      what to do now, and I think I must do something wrong...Please help,
      thanks!
      >
      >
      >

      Comment

      • G Himangi

        #4
        Re: OCX(COM) Interop...Passi ng pointer of structure to function

        >
        I think the first problem is solved by the declaration
        "CharSet=CharSe t.Ansi" (I think..)
        >
        Yes, you are right.

        Another problem I noticed was the Pack=8 attribute. Is this type of packing
        specified on the original structure? If not, leave it out.

        ---------
        - G Himangi, LogicNP Software http://www.ssware.com
        Shell MegaPack: GUI Controls For Drop-In Windows Explorer like File/Folder
        Browsing Functionality (.Net & ActiveX Editions).
        EZNamespaceExte nsions: Develop namespace extensions rapidly in .Net and
        MFC/ATL/C++
        EZShellExtensio ns: Develop all shell extensions,expl orer bars and BHOs
        rapidly in .Net & MFC/ATL/C++
        ---------

        "Mingyi" <Mingyi@discuss ions.microsoft. comwrote in message
        news:B7BB13AE-FE06-47B6-9901-78E81075B6E5@mi crosoft.com...
        >
        Hi,
        >
        I think the first problem is solved by the declaration
        "CharSet=CharSe t.Ansi" (I think..)
        >
        For the second one, I used to marshall the bool to 1 byte counterpart, but
        the problem persists..
        >
        Thanks for the reply anyway.
        >
        >
        "G Himangi" wrote:
        >
        >Dont know about the actual call but I can see a few problems with your
        >structure definition :
        >>
        >1. The UserName,passwo rd and address are defined as ByValTStr (means Ansi
        >or
        >Uni depending on platform) when in fact they are defined as ANSI in the
        >original structure.
        >>
        >2. The bDirectDrawMode is defined as bool (which marshals to 4 bytes) but
        >the origianl structure defines it as smallcase bool which in C++ I think
        >occupies 1 byte.
        >>
        >---------
        >- G Himangi, LogicNP Software http://www.ssware.com
        >Shell MegaPack: GUI Controls For Drop-In Windows Explorer like
        >File/Folder
        >Browsing Functionality (.Net & ActiveX Editions).
        >EZNamespaceExt ensions: Develop namespace extensions rapidly in .Net and
        >MFC/ATL/C++
        >EZShellExtensi ons: Develop all shell extensions,expl orer bars and BHOs
        >rapidly in .Net & MFC/ATL/C++
        >---------
        >>
        >"Mingyi" <Mingyi@discuss ions.microsoft. comwrote in message
        >news:4C4CAA2 0-EB0D-4D78-8C1D-FE1832B11C99@mi crosoft.com...
        Hi,
        >
        I have the following question regarding communicating with a OCX
        control
        using C#. Idon't have access to the ocx code, so my c# code is actually
        mimic
        the behavior of C++ counterparts. Basically, I have problem passing a
        structure to a function.
        >
        Here is the C++ part code:
        >
        //*************** *************** **********
        typedef struct
        {
        char TypeID;
        char UserName[20];
        char Password[20];
        char UrlAddress[255];
        int iStreamChannel;
        bool bDirectDrawMode ;
        }CONNECT_DATA;
        >
        CONNECT_DATA m_ConnectData;
        >
        // after initializing m_ConnectData
        >
        int ret= InitConnectData ((PBYTE)&m_Conn ectData);
        >
        //*************** *************** **********
        >
        In C# when I drop this active control to my app, the interface for the
        function
        InitConnectData has be given as follows
        >
        InitConnectData (ref byte)
        >
        So the following is what I did in the C# part.
        >
        //*************** *************** **********
        >
        [StructLayout(La youtKind.Sequen tial,CharSet=Ch arSet.Ansi,Pack =8)]
        public unsafe struct CONNECT_DATA
        {
        public byte TypeID;
        >
        [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
        public string UserName;
        >
        [MarshalAs(Unman agedType.ByValT Str, SizeConst = 20)]
        public string Password;
        >
        [MarshalAs(Unman agedType.ByValT Str, SizeConst = 255)]
        public string UrlAddress;
        >
        public int iStreamChannel;
        public bool bDirectDrawMode ;
        >
        }
        >
        CONNECT_DATA connect_data = new CONNECT_DATA();
        >
        // After initializing all the fields
        >
        IntPtr pnt =
        Marshal.AllocCo TaskMem(Marshal .SizeOf(connect _data));
        try
        {
        Marshal.Structu reToPtr(connect _data, pnt, false);
        byte[] buffer = new byte[Marshal.SizeOf( connect_data)];
        Marshal.Copy(pn t, buffer, 0,
        Marshal.SizeOf( connect_data));
        int ret = axNetworkCamera Link2.InitConne ctData(ref
        buffer[0]);
        }
        //*************** *************** **********
        >
        But it seems that the function never gets the structure right, for it
        always
        gives the wrong return value.
        >
        I tried to "Tlbimp" the original DLL, change the IL code so that the
        "InitConnectDat a(uint8&)" becames "InitConnectDat a(native int)", and in
        C#
        the interface becames "InitConnectDat a(System.IntPtr )", but error
        occurs,
        stating that
        >
        "System.Runtime .InteropService s.COMException
        (0x80020005): Type mismatch. at
        System.RuntimeT ype.ForwardCall ToInvokeMember( String memberName,
        BindingFlags
        flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)"
        >
        I guess it is because uint8 is 8 bit and native int is 32 bit...I
        really
        don't know
        what to do now, and I think I must do something wrong...Please help,
        thanks!
        >
        >>
        >>
        >>

        Comment

        Working...