none
Interop C++ dll from vb.net RRS feed

  • Question

  • Hi,

    I am writing this only after exhausting effort to search and find the solution was unsuccessful. 

    I am using Visual Studio 2005. The Test123 function written in C++ should be called from vb.net by using Interop Services. The Testing.dll is a CLR module.

    Below is a simplified version of the C++ structure :

    typedef struct TEST_STRUCT
    {
       long lTotal;
       int nRow;
       int nCol;
       CString sName;
       BOOL bFound;
       int item[100];
    } TEST;

    Below is a simplified version of the structure declared in vb.net :

        <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _
        Public Structure TEST_STRUCT
            ' ''<System.Runtime.InteropServices.FieldOffsetAttribute(0)> _
            Public lTotal As Integer
            Public nRow As Integer
            Public nCol As Integer
            <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)> _
            Public sName As String
            <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)> _
            Public bFound As Boolean

            '<System.Runtime.InteropServices.MarshalAsAttribute _
            '(System.Runtime.InteropServices.UnmanagedType.SafeArray, SafeArraySubType:=Runtime.InteropServices.VarEnum.VT_I4)> _
            <System.Runtime.InteropServices.MarshalAsAttribute _
            (System.Runtime.InteropServices.UnmanagedType.LPArray, SizeConst:=100)> _
                Public Item() As Integer
        End Structure

        Public Declare Auto Function Test123 Lib "Testing.dll" () As TEST_STRUCT
        
        What can work :
        1) I can call the module Test123 from vb.net and it can run.
        2) I can interop data for lTotal, nRow and nCol and receive at vb.net without any problem.
        
        What my questions are :
        1) How to interop data for sName, bFound and item[100]? 
        2) Which part I am wrong? 
        3) How should I declare the structure in vb.net to interop these data?
        4) Can Interop support CString directly?
        5) Is there any indirect way of marshaling which can work, such as doing the Interop in C# and then call from vb.net?
        
        Your guidance on solving this problem is very much appreciated.
        
        Thanks,
        Goutam

    Friday, November 13, 2009 4:27 AM

Answers

  • Hi,

    CString is not supported directly in Interop during managed world and unmanged world. you can consider replacing it with char* or TCHAR*, so, the struct will be:

    typedef struct TEST_STRUCT

    {

       long lTotal;

       int nRow;

       int nCol;

       char* sName;

       BOOL bFound;

       int item[100];

    } TEST;

    And you can try following code to declare the struct in VB.NET:

    <System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)>  _

    Public Structure TEST_STRUCT

       

        '''int

        Public lTotal As Integer

       

        '''int

        Public nRow As Integer

       

        '''int

        Public nCol As Integer

       

        '''char*

        <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)>  _

        Public sName As String

       

        '''BOOL->int

        Public bFound As Integer

       

        '''int[100]

    System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=100, ArraySubType:=System.Runtime.InteropServices.UnmanagedType.I4)>  _

        Public item() As Integer

    End Structure

     

    Hope this can help:)

     

    Thanks,

    Eric


    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    Thursday, November 19, 2009 7:10 AM

All replies

  • Hi,

    CString is not supported directly in Interop during managed world and unmanged world. you can consider replacing it with char* or TCHAR*, so, the struct will be:

    typedef struct TEST_STRUCT

    {

       long lTotal;

       int nRow;

       int nCol;

       char* sName;

       BOOL bFound;

       int item[100];

    } TEST;

    And you can try following code to declare the struct in VB.NET:

    <System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)>  _

    Public Structure TEST_STRUCT

       

        '''int

        Public lTotal As Integer

       

        '''int

        Public nRow As Integer

       

        '''int

        Public nCol As Integer

       

        '''char*

        <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)>  _

        Public sName As String

       

        '''BOOL->int

        Public bFound As Integer

       

        '''int[100]

    System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst:=100, ArraySubType:=System.Runtime.InteropServices.UnmanagedType.I4)>  _

        Public item() As Integer

    End Structure

     

    Hope this can help:)

     

    Thanks,

    Eric


    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    Thursday, November 19, 2009 7:10 AM
  • Hello Eric,

    Thanks for your reply. It was really helpful.

    When I thoroughly tested the program, I can pass in structure as a parameter and it can work well.
    But, when I try to receive structure as a returned value, I get error "Method's type signature is not PInvoke compatible".
    Please take note that my original question requires structure as a returned value.

    Any guidance will be amazing.

    cheers,
    Goutam
    • Edited by Ggoutam7 Tuesday, December 1, 2009 1:12 AM Incomplete
    Wednesday, November 25, 2009 9:37 AM