none
Type mismatch - System.Runtime.InteropServices.COMException was unhandled by user code

    Question

  • Type mismatch error is appearing when passing params object[] array to com component made in VB6.0

    object[] myObj = new object [] { "@Parameter1", "adInteger", 4, 40 };
     
    rsPackage = obj.RunSPReturnRS(conn, "MySPName", ref myObj);
     
    RunSPReturnRS is one of method from Com include in my C# Web Application.
     
    But I am getting type mismatch error for this myobj object.

    Thanks in advance

    Tuesday, April 03, 2012 10:25 AM

Answers

  • Hello Rajendra,

    1. I think the type mismatch exception is likely raised by the VB6.0 COM component.

    2. We just do not know which element(s) of the array (that is received by the COM component) contain(s) the VARIANT of incorrect type.

    3. One way to find out is to write and use a simple DLL API written in C++ as follows :

    // HelperDLL.cpp : Defines the exported functions for the DLL application.
    //
    #include "stdafx.h"
    #include <windows.h>
    #include <oleauto.h>
    #include <stdio.h>
    extern "C" __declspec(dllexport) void __stdcall CheckVariantType(VARIANT* pvar)
    {
      char szMessage[256];
      VARTYPE vt = V_VT(pvar);
      
      sprintf(szMessage, "%d", (int)vt);
      
      MessageBox(NULL, szMessage, "Check Variant Type", MB_OK);  
    }

    4. Use it in a VB application that has successfully called the RunSPReturnRS() method.

    5. You might also want to write a dummy version of a COM component (in VB6.0) that exposes a dummy RunSPReturnRS() method. This is to test what type of VARIANT the interop marshaler will generate for the "myObj" array.

    6. A sample dummy RunSPReturnRS() method in VB6.0 might be something like :

    Declare Sub CheckVariantType Lib "HelperDLL" (ByRef var As Variant)
    Public Function RunSPReturnRS(ByVal Conn As String, ByVal SPName As String, ParamArray args() As Variant) As Integer
        Dim v As Variant
        
        For Each v In args
            CheckVariantType (v)
        Next
        
        RunSPReturnRS = 0
        
    End Function

    7. The above points are meant to help towards determining the correct data type to use for the "myObj" array.

    8. Best of luck, Rajendra.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, April 11, 2012 4:54 AM

All replies

  • Hello Rajendra,

    Pls show us the method signature of RunSPReturnRS().

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, April 03, 2012 10:40 AM
  • Thanks for reply.

    Please find below signature of RunSPReturnRS().

    RunSPReturnRS(string Conn, string SPName, params objects[] @params)

    I am getting error for passing object array parameter.

    Tuesday, April 03, 2012 10:48 AM
  • remove ref keyword & directly specify the arguments as below.

    rsPackage = obj.RunSPReturnRS(conn, "MySPName", "@Parameter1", "adInteger", 4, 40);


    Please mark this post as answer if it solved your problem. Happy Programming!

    Tuesday, April 03, 2012 11:31 AM
  • Thanks Adavesh.

    But the way you suggest to pass paramerte is giving me error, because RunSPReturnRS method takes only 3 paramertes.

    Tuesday, April 03, 2012 12:05 PM
  • Hi Adavesh,

    Can you suggest me the proper way to directly specify the arguments.

    Thanks in advance.

    Wednesday, April 04, 2012 11:51 AM
  • Hello Rajendra,

    1. Is the VB6.0 definition of the RunSPReturnRS() function defined something like the following ? :

    Public Function RunSPReturnRS(ByVal Conn As String, ByVal SPName As String, ParamArray args() As Variant) As Integer
    
    	...
    	...
    	...
    
    End Function
    

    2. This should give rise to the folllowing IDL definition :

            [id(0x60030000), vararg]
            HRESULT RunSPReturnRS(
                            [in] BSTR Conn, 
                            [in] BSTR SPName, 
                            [in, out] SAFEARRAY(VARIANT)* args, 
                            [out, retval] short* );

    3. Can you confirm the above ?

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, April 04, 2012 3:22 PM
  • I found that your RunSPReturnRS didn't have a Ref argument, but you used it with a Ref.

    Have you tried to move the Ref key words? Or add a ref to the RunSPReturnRS method?


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    Monday, April 09, 2012 2:04 AM
    Moderator
  • Hello Bio,

    The signature for my VB 6.0 is

    Function RunSPReturnRS(ByVal strConnString As String, ByVal strSP As String, ParamArray params() As Variant) As ADODB.Recordset

    ....

    .....

    ......


    Thanks for your help.
    • Edited by Rajendra.Patil Monday, April 09, 2012 1:46 PM for formating changes
    Monday, April 09, 2012 12:23 PM
  • Hi Bio,

    Defination of VB6.0 function

    Function RunSPReturnRS(ByVal strConnString As String, ByVal strSP As String, ParamArray params() As Variant) As ADODB.Recordset

    Thanks for help.

    Monday, April 09, 2012 12:24 PM
  • Hello Rajendra,

    1. >> Function RunSPReturnRS(ByVal strConnString As String, ByVal strSP As String, ParamArray params() As Variant) As ADODB.Recordset...

    1.1 In this case the C# code that you used to make the call to RunSPReturnRS() :

    object[] myObj = new object [] { "@Parameter1", "adInteger", 4, 40 }; 
     
    rsPackage = obj.RunSPReturnRS(conn, "MySPName", ref myObj); 

    is correct.

    1.2 The type mismatch error is likely an error detected and generated from the COM server (which was written in VB6.0).

    2. When you make the call to RunSPReturnRS() using the object array "myObj", one of the members of the array is likely not of the correct type expected by the COM component.

    2.1 Here is an example of an implementation of RunSPReturnRS() that can result in this :

    Public Function RunSPReturnRS(ByVal Conn As String, ByVal SPName As String, ParamArray args() As Variant) As Integer
        
        Dim i As Single
        
        '' We know that args(0) is a string
        '' "@Parameter1" and so assigning a
        '' Single to a string will cause a
        '' type mismatch exception.
        i = args(0)
    
        RunSPReturnRS = 0
    
    End Function
    

    3. Do you have access to the actual source codes of RunSPReturnRS() ?

    3.1 If you do you can check to see the actual type that is expected of each item of the args() array.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Monday, April 09, 2012 3:21 PM
  • Thanks for reply,

    Here is the actual type that is expected of each item of the args() array.

    Actual source code of RunSPReturnRS from VB 6.0

    Set rs = objDB.RunSPReturnRS(ConnString, "SP Name", Array("@SP_Param1", adInteger, 4, CLng(40)))

    ..........

    ..........

    ' Below is array - Array("@SP_Param1", adInteger, 4, CLng(40))

    ..........

    ..........

    adInteger is member of ADODB.DataTypeEnum.

    After passing the parameter as per the actual type required in VB 6.0

    I am getting below error -

    Exception Details: System.Runtime.InteropServices.COMException: Type mismatch

    Source Error:

    long test = 40;

    Line 31:             object[] myObj = new object[] { "@division_code_int", ADODB.DataTypeEnum.adInteger, 4, test};
    Line 32:
    Line 33:             rsPackage = obj.RunSPReturnRS(conn, "SP_NAME", ref myObj);

    Stack Trace:


    [COMException (0x800a000d): Type mismatch]
       escceDBManCsharp.DatabaseClass.RunSPReturnRS(String strConnString, String strSP, Object[]& params) +0

    So please suggest what mistake is done by me here.

    Thanks,

    Rajendra.




    • Edited by Rajendra.Patil Tuesday, April 10, 2012 9:38 AM updating for error stak trace
    Tuesday, April 10, 2012 9:04 AM
  • Hello Rajendra,

    1. I believe the problem is either with the 2nd object array element (the value of which is to be taken from ADODB.DataTypeEnum) and/or with the last element (in which you have specified "test").

    2. The array element that uses "test" as its value is very likely a problem because "test" is of type long.

    2.1 A long in C# is 64-bits whereas a long in VB6.0 is 32-bits.

    2.2 For "test", I suggest that instead of declaring it as long, you declare it as Int32 :

    Int32 test = 40;

    3. As for the 2nd object array element (the value of which is to be taken from ADODB.DataTypeEnum) : enums are generally translated into 32-bit integers.

    3.1 See if you can code something like the following :

    Int32 MyAdInteger = (Int32)(ADODB.DataTypeEnum.adInteger);
    ...
    ...
    ...
    object[] myObj = new object[] { "@division_code_int", MyAdInteger, 4, test};
    
    

    4. However, pls try changing the type for "test" first and do not use the MyAdInteger solution.

    4.1 Things might work out correctly after changing "test" from long to Int32.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Tuesday, April 10, 2012 11:20 AM
  • Hi Lim Bio,

    Thanks for quick reply.

    I follow the solution given by you, but things are not working as per expecation.

    I tried by both the 2.2 and 3.1 solutions here.

    I am getting the same error. Please see below code if you find what silly mistake is done by me here.

    ADODB.Recordset rsPackage = default(ADODB.Recordset);
                Int32 test = 40;
                Int32 MyAdInteger = (Int32)(ADODB.DataTypeEnum.adInteger);
                object[] myObj = new object[] { "@SP_Param1", MyAdInteger, 4, test };
                rsPackage = obj.RunSPReturnRS(conn, "SPName", ref myObj);
    ....
    ......

    Thanks,

    Rajendra.



    Tuesday, April 10, 2012 1:38 PM
  • Hello Rajendra,

    1. I think the type mismatch exception is likely raised by the VB6.0 COM component.

    2. We just do not know which element(s) of the array (that is received by the COM component) contain(s) the VARIANT of incorrect type.

    3. One way to find out is to write and use a simple DLL API written in C++ as follows :

    // HelperDLL.cpp : Defines the exported functions for the DLL application.
    //
    #include "stdafx.h"
    #include <windows.h>
    #include <oleauto.h>
    #include <stdio.h>
    extern "C" __declspec(dllexport) void __stdcall CheckVariantType(VARIANT* pvar)
    {
      char szMessage[256];
      VARTYPE vt = V_VT(pvar);
      
      sprintf(szMessage, "%d", (int)vt);
      
      MessageBox(NULL, szMessage, "Check Variant Type", MB_OK);  
    }

    4. Use it in a VB application that has successfully called the RunSPReturnRS() method.

    5. You might also want to write a dummy version of a COM component (in VB6.0) that exposes a dummy RunSPReturnRS() method. This is to test what type of VARIANT the interop marshaler will generate for the "myObj" array.

    6. A sample dummy RunSPReturnRS() method in VB6.0 might be something like :

    Declare Sub CheckVariantType Lib "HelperDLL" (ByRef var As Variant)
    Public Function RunSPReturnRS(ByVal Conn As String, ByVal SPName As String, ParamArray args() As Variant) As Integer
        Dim v As Variant
        
        For Each v In args
            CheckVariantType (v)
        Next
        
        RunSPReturnRS = 0
        
    End Function

    7. The above points are meant to help towards determining the correct data type to use for the "myObj" array.

    8. Best of luck, Rajendra.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, April 11, 2012 4:54 AM