Unmanaged DLL structure conversion problem (unsigned char pointer)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • edsunder
    New Member
    • Oct 2009
    • 5

    Unmanaged DLL structure conversion problem (unsigned char pointer)

    I'm making a "wrapper" for an unmanaged DLL (written, I'm fairly certain in C). I have a c++ "wrapper" that I'm trying to convert to VB.net. I've got most of the program working, but I've hit a brick wall.

    I'm trying to convert the following two structures from their c++ versions to their vb.net versions. I cannot be sure which is the problem because both must be passed at the same time. The error I am getting is thrown by the object and indicates "Invalid structure size specified". I can cause this error on other objects when I either don't set the dwSize variable, leave off a parameter or change the parameter type incorrectly. Note that the dwSize parameter is supposed to contain the size of each structure. I'm successfully calculating that for my other structures and I'm using the same method on these and the results appear correct, so I do not believe the problem is found there. The object uses a lot of structures and the rest of them are working. These two are the only ones with a) an unsigned character pointer b) an unsigned long array and c) doubles.

    C++ versions:
    Code:
    //
    // Texture data
    //
    
    typedef struct tagFACE_TEXTUREDATA
    {
    	DWORD dwSize;
    	LONG  nTextureType;
    	LONG  nWidth;
    	LONG  nHeight;
    	LONG  nBitCount;
    	DWORD dwPalette[256];
    	BYTE* pImageData;
    	CHAR  szImageFile[260];
    	LONG  nColorTranslation;
    	DWORD dwColor;
    	LONG  nTextureSize;
    	LONG  nTextureScaling;
    	BYTE* pMaskData;
    	CHAR  szMaskFile[260];
    } 
    FACE_TEXTUREDATA;
    
    //
    // Texture properties
    //
     
    typedef struct tagFACE_TEXTUREPROP
    {
    	DWORD  dwSize;
    	DOUBLE eGloss;
    	DOUBLE eContrast;
    	BOOL   bRepeat;
    	DOUBLE eDropX;
    	DOUBLE eDropY;
    	DOUBLE ePlacingPointX;
    	DOUBLE ePlacingPointY;
    	DOUBLE eWidth;
    	DOUBLE eHeight;
    	LONG   nTransformation;
    } 
    FACE_TEXTUREPROP;
    Here are my VB structures:

    Code:
        ' Texture data
        Public Structure FACE_TEXTUREDATA
            <MarshalAs(UnmanagedType.U4)> Public dwSize As UInteger
            <MarshalAs(UnmanagedType.I4)> Public nTextureType As Integer
            <MarshalAs(UnmanagedType.I4)> Public nWidth As Integer
            <MarshalAs(UnmanagedType.I4)> Public nHeight As Integer
            <MarshalAs(UnmanagedType.I4)> Public nBitCount As Integer
            <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.U4, SizeConst:=256)> Public dwPalette() As UInteger
            <MarshalAs(UnmanagedType.I1)> Public pImageData As Byte
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szImageFile As String
            <MarshalAs(UnmanagedType.I4)> Public nColorTranslation As Integer
            <MarshalAs(UnmanagedType.U4)> Public dwColor As UInteger
            <MarshalAs(UnmanagedType.I4)> Public nTextureSize As Integer
            <MarshalAs(UnmanagedType.I4)> Public nTextureScaling As Integer
            <MarshalAs(UnmanagedType.I1)> Public pMaskData As Byte
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public szMaskFile As String
        End Structure
    
        ' Texture properties
        Public Structure FACE_TEXTUREPROP
            <MarshalAs(UnmanagedType.U4)> Public dwSize As UInteger
            <MarshalAs(UnmanagedType.R8)> Public eGloss As Double
            <MarshalAs(UnmanagedType.R8)> Public eContrast As Double
            <MarshalAs(UnmanagedType.I4)> Public bRepeat As Integer
            <MarshalAs(UnmanagedType.R8)> Public eDropX As Double
            <MarshalAs(UnmanagedType.R8)> Public eDropY As Double
            <MarshalAs(UnmanagedType.R8)> Public ePlacingPointX As Double
            <MarshalAs(UnmanagedType.R8)> Public ePlacingPointY As Double
            <MarshalAs(UnmanagedType.R8)> Public eWidth As Double
            <MarshalAs(UnmanagedType.R8)> Public eHeight As Double
            <MarshalAs(UnmanagedType.I4)> Public nTransformation As Integer
        End Structure
    I don't think I'm missing any parameters - the help file seems to agree with me on this, but it's theoretically possible that there is something missing (though I don't think so for other reasons as well). My suspicion is that it's dwPalette, pImageData or pMaskData with (in my uninformed opinion) more suspicion on the pImageData and pMaskData.

    Any help would be appreciated. I've pretty much exhasted my knowledge of this stuff a while ago. That said, I am very close to the finish line and if I can solve this, I believe that will be the last thing I need to make this work.
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    Have you tried UnmanagedType.L PStr or UnmanagedType.L PArray maybe?
    Or maybe even IntPtr?
    I don't know how to do it with structs.
    I know for function calls I've seen luck with StringBuilder for char*

    Comment

    • edsunder
      New Member
      • Oct 2009
      • 5

      #3
      Thanks for your reply!

      I can't seem to make it let me use LPArray even if I convert it to an array:
      Code:
      <MarshalAs(UnmanagedType.LPArray)> Public pImageData() As Byte
      it tells me "System.TypeLoa dException: Cannot marshal field 'pImageData' of type 'FACE_TEXTUREDA TA': Invalid managed/unmanaged type combination (Arrays fields must be paired with ByValArray or SafeArray)."

      What am I missing?

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        That was only for the char*, not the whole thing

        Comment

        • edsunder
          New Member
          • Oct 2009
          • 5

          #5
          I'm not sure I understand what you mean by that. Could you explain maybe with an example? Thanks for your help.

          Comment

          • Plater
            Recognized Expert Expert
            • Apr 2007
            • 7872

            #6
            Oh ok, the structure for VBNET in this is much different then c#
            Hmm I don't know.

            Looking back at the struct its really got to be IntPtr (or some unmanaged pointer type) and you need to use special functions to retreieve the unmanaged data

            Comment

            • edsunder
              New Member
              • Oct 2009
              • 5

              #7
              After looking at this for a week, I'm thinking that I'm missing a parameter. I've contacted the developer of the DLL. Let's hope they respond. :) Thanks for your help.

              Comment

              • edsunder
                New Member
                • Oct 2009
                • 5

                #8
                Turns out it was a combination of a missing parameter and I needed to use Pack := 4 in the StructLayout

                Comment

                Working...