C# 传结构体数组到C++dll中

时间:2022-08-30 19:08:48
C++ dll 的参数里有一个结构体数组,是以指针给出的。C#怎么传递

15 个解决方案

#1


C#需要声明
类似
从 Kernel32.dll 导出的 GetSystemTime。 
VOID GetSystemTime(LPSYSTEMTIME lpSystemTime);
传递到该函数的初始结构包含以下元素:
typedef struct _SYSTEMTIME { 
    WORD wYear; 
    WORD wMonth; 
    WORD wDayOfWeek; 
    WORD wDay; 
    WORD wHour; 
    WORD wMinute; 
    WORD wSecond; 
    WORD wMilliseconds; 
} SYSTEMTIME, *PSYSTEMTIME;
在该示例中,SystemTime 类包含表示为类成员的原始结构的元素。StructLayoutAttribute 属性经过设置,以确保成员在内存中按它们的出现顺序依次排列。
LibWrap 类包含 GetSystemTime 方法的托管原型,默认情况下,它将 SystemTime 类作为 In/Out 参数进行传递。必须用 InAttribute 和 OutAttribute 属性声明该参数,因为作为引用类型的类在默认情况下将作为输入参数进行传递。为使调用方接收结果,必须显式应用这些方向属性。App 类创建 SystemTime 类的一个新实例,然后访问其数据字段。
声明原型
[Visual Basic]
' Declares a class member for each structure element.
< StructLayout(LayoutKind.Sequential )> _
Public Class SystemTime
   Public year As Short
   ...
   Public milliseconds As Short 
End Class 'SystemTime

Public Class LibWrap
   ' Declares a managed prototype for the unmanaged function.
   Declare Sub GetSystemTime Lib "Kernel32.dll" ( <[In], Out> ByVal st _
      As SystemTime )
End Class 'LibWrap
[C#]
// Declares a class member for each structure element.
[ StructLayout( LayoutKind.Sequential )]
public class SystemTime 
{
   public ushort year; 
   ... 
   public ushort milliseconds; 
}

public class LibWrap 
{
   // Declares a managed prototype for the unmanaged function.
   [ DllImport( "Kernel32.dll" )]
   public static extern void GetSystemTime( [In,Out] SystemTime st );
}
调用函数
[Visual Basic]
Public Class App
   Public Shared Sub Main()
      Dim st As New SystemTime()
      LibWrap.GetSystemTime( st )
      Console.Write( "The Date and Time is: " )
      ...
   End Sub 'Main
End Class 'App
[C#]
public class App
{
   public static void Main()
   {
      SystemTime st = new SystemTime();
      LibWrap.GetSystemTime( st );
      Console.Write( "The Date and Time is: " );
      ...
   }
}

#2


谢谢。我是想传递结构体数组进dll。
dll原形HRESULT Add(struct Struct_data* datatag,int num);
num为结构体数组长度

#3


IntPtr Add([MarshalAs(UnManagedType.LPArray)]Struct_data[] datatag,int num);

#4


谢谢,我试试

#5


我在C#中怎么是Add(ref Struct_data datatag,int num);
如何改为IntPtr Add([MarshalAs(UnManagedType.LPArray)]Struct_data[] datatag,int num);

#6


MARK
学习

#7


再给你一段代码,直接抄msdn的
[ StructLayout( LayoutKind.Sequential )]
public struct MyPoint 
{
   public int x; 
   public int y;
   public MyPoint( int x, int y )
   {
      this.x = x;
      this.y = y;
   }
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyPerson 
{
   public String first; 
   public String last;
   public MyPerson( String first, String last )
   {
      this.first = first;
      this.last = last;
   }
}

public class LibWrap
{
   // Declares a managed prototype for an array of integers by value.
   // The array size cannot be changed, but the array is copied back.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfInts([In, Out] int[] array, int size );
   
   // Declares a managed prototype for an array of integers by reference.
   // The array size can change, but the array is not copied back 
   // automatically because the marshaler does not know the resulting size.
   // The copy must be performed manually.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestRefArrayOfInts( ref IntPtr array, 
      ref int size );
   
   // Declares a managed prototype for a matrix of integers by value.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestMatrixOfInts([In, Out] int[,] pMatrix, 
      int row );   
   // Declares a managed prototype for an array of strings by value.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStrings( [In, Out] 
      String[] stringArray, int size );
   
   // Declares a managed prototype for an array of structures with integers.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStructs([In, Out] MyPoint[] 
      pointArray, int size ); 
   
   // Declares a managed prototype for an array of structures with strings.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStructs2( [In, Out] 
      MyPerson[] personArray, int size );
}
调用函数
[C#]
public class App
{
   public static void Main()
   {
      // array ByVal 
      int[] array1 = new int[ 10 ];
      Console.WriteLine( "Integer array passed ByVal before call:" );
      for( int i = 0; i < array1.Length; i++ )
      {
         array1[ i ] = i;
         Console.Write( " " + array1[ i ] );
      }
      int sum1 = LibWrap.TestArrayOfInts( array1, array1.Length );
      Console.WriteLine( "\nSum of elements:" + sum1 );
      Console.WriteLine( "\nInteger array passed ByVal after call:" );
      
      foreach( int i in array1 )
      {
         Console.Write( " " + i );
      }   
      
      // array ByRef 
      int[] array2 = new int[ 10 ];
      int size = array2.Length;
      Console.WriteLine( "\n\nInteger array passed ByRef before call:" );
      for( int i = 0; i < array2.Length; i++ )
      {
         array2[ i ] = i;
         Console.Write( " " + array2[ i ] );
      }
      IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf( size ) 
         * array2.Length );
      Marshal.Copy( array2, 0, buffer, array2.Length );
      
      int sum2 = LibWrap.TestRefArrayOfInts( ref buffer, ref size );
      Console.WriteLine( "\nSum of elements:" + sum2 );
      if( size > 0 )
      {
         int[] arrayRes = new int[ size ];
         Marshal.Copy( buffer, arrayRes, 0, size );
         Marshal.FreeCoTaskMem( buffer );
         Console.WriteLine( "\nInteger array passed ByRef after call:" );
         foreach( int i in arrayRes )
         {
            Console.Write( " " + i );
         }
      }
      else
         Console.WriteLine( "\nArray after call is empty" );
         
      // matrix ByVal 
      const int DIM = 5;
      int[,] matrix = new int[ DIM, DIM ];
      
      Console.WriteLine( "\n\nMatrix before call:" );
      for( int i = 0; i < DIM; i++ )
      {
         for( int j = 0; j < DIM; j++ )
         {
            matrix[ i, j ] = j;
            Console.Write( " " + matrix[ i, j ] );
         }
         Console.WriteLine( "" );
      }
      int sum3 = LibWrap.TestMatrixOfInts( matrix, DIM );
      Console.WriteLine( "\nSum of elements:" + sum3 );
      Console.WriteLine( "\nMatrix after call:" );
      for( int i = 0; i < DIM; i++ )
      {
         for( int j = 0; j < DIM; j++ )
         {
            Console.Write( " " + matrix[ i, j ] );
         }
         Console.WriteLine( "" );
      }
      
      // string array ByVal 
      String[] strArray = { "one", "two", "three", "four", "five" };
      Console.WriteLine( "\n\nString array before call:" );
      foreach( String s in strArray )
         Console.Write( " "+ s );
      int lenSum = LibWrap.TestArrayOfStrings( strArray, strArray.Length );
      Console.WriteLine( "\nSum of string lengths:" + lenSum );
      Console.WriteLine( "\nString array after call:" );
      foreach( String s in strArray )
      {
         Console.Write( " " + s );
      }   
      
      // struct array ByVal 
      MyPoint[] points = { new MyPoint(1,1), new MyPoint(2,2), new MyPoint(3,3) };
      Console.WriteLine( "\n\nPoints array before call:" );
      foreach( MyPoint p in points )
         Console.WriteLine( "x = {0}, y = {1}", p.x, p.y );
      int allSum = LibWrap.TestArrayOfStructs( points, points.Length );
      Console.WriteLine( "\nSum of points:" + allSum );
      Console.WriteLine( "\nPoints array after call:" );
      foreach( MyPoint p in points )
         Console.WriteLine( "x = {0}, y = {1}", p.x, p.y );      
         
      // struct with strings array ByVal 
      MyPerson[] persons = { new MyPerson( "Kim", "Akers" ), 
      new MyPerson( "Adam", "Barr" ), new MyPerson( "Jo", "Brown" )};
      
      Console.WriteLine( "\n\nPersons array before call:" );
      foreach( MyPerson pe in persons )
        Console.WriteLine( "first = {0}, last = {1}", pe.first, pe.last );
      int namesSum = LibWrap.TestArrayOfStructs2( persons, persons.Length );
      Console.WriteLine( "\nSum of name lengths:" + namesSum );
      Console.WriteLine( "\n\nPersons array after call:" );
      foreach( MyPerson pe in persons )
        Console.WriteLine( "first = {0}, last = {1}", pe.first, pe.last );
   }
}

#8


根本不会

我还是循序渐进把

#9


必须用dllimport吗?我直接引用的。

#10


c++ dll
是什么类型的dll 

win32 的
还是com的
还是托管的
???

#11


com的

#12


你可以把结构体封装成COM对象,然后传递结构体的接口

#13


能说具体点吗?不明白

#14


http://msdn2.microsoft.com/en-us/library/4h56szat(VS.80).aspx

#15


看着不舒服,整理下看

[   StructLayout(   LayoutKind.Sequential   )] 
public   struct   MyPoint   

      public   int   x;   
      public   int   y; 
      public   MyPoint(   int   x,   int   y   ) 
      { 
            this.x   =   x; 
            this.y   =   y; 
      } 

[   StructLayout(   LayoutKind.Sequential,   CharSet=CharSet.Ansi   )] 
public   struct   MyPerson   

      public   String   first;   
      public   String   last; 
      public   MyPerson(   String   first,   String   last   ) 
      { 
            this.first   =   first; 
            this.last   =   last; 
      } 


public   class   LibWrap 

      //   Declares   a   managed   prototype   for   an   array   of   integers   by   value. 
      //   The   array   size   cannot   be   changed,   but   the   array   is   copied   back. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfInts([In,   Out]   int[]   array,   int   size   ); 
      
      //   Declares   a   managed   prototype   for   an   array   of   integers   by   reference. 
      //   The   array   size   can   change,   but   the   array   is   not   copied   back   
      //   automatically   because   the   marshaler   does   not   know   the   resulting   size. 
      //   The   copy   must   be   performed   manually. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestRefArrayOfInts(   ref   IntPtr   array,   
            ref   int   size   ); 
      
      //   Declares   a   managed   prototype   for   a   matrix   of   integers   by   value. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestMatrixOfInts([In,   Out]   int[,]   pMatrix,   
            int   row   );       
      //   Declares   a   managed   prototype   for   an   array   of   strings   by   value. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStrings(   [In,   Out]   
            String[]   stringArray,   int   size   ); 
      
      //   Declares   a   managed   prototype   for   an   array   of   structures   with   integers. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStructs([In,   Out]   MyPoint[]   
            pointArray,   int   size   );   
      
      //   Declares   a   managed   prototype   for   an   array   of   structures   with   strings. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStructs2(   [In,   Out]   
            MyPerson[]   personArray,   int   size   ); 

调用函数 
[C#] 
public   class   App 

      public   static   void   Main() 
      { 
            //   array   ByVal   
            int[]   array1   =   new   int[   10   ]; 
            Console.WriteLine(   "Integer   array   passed   ByVal   before   call: "   ); 
            for(   int   i   =   0;   i   <   array1.Length;   i++   ) 
            { 
                  array1[   i   ]   =   i; 
                  Console.Write(   "   "   +   array1[   i   ]   ); 
            } 
            int   sum1   =   LibWrap.TestArrayOfInts(   array1,   array1.Length   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum1   ); 
            Console.WriteLine(   "\nInteger   array   passed   ByVal   after   call: "   ); 
            
            foreach(   int   i   in   array1   ) 
            { 
                  Console.Write(   "   "   +   i   ); 
            }       
            
            //   array   ByRef   
            int[]   array2   =   new   int[   10   ]; 
            int   size   =   array2.Length; 
            Console.WriteLine(   "\n\nInteger   array   passed   ByRef   before   call: "   ); 
            for(   int   i   =   0;   i   <   array2.Length;   i++   ) 
            { 
                  array2[   i   ]   =   i; 
                  Console.Write(   "   "   +   array2[   i   ]   ); 
            } 
            IntPtr   buffer   =   Marshal.AllocCoTaskMem(   Marshal.SizeOf(   size   )   
                  *   array2.Length   ); 
            Marshal.Copy(   array2,   0,   buffer,   array2.Length   ); 
            
            int   sum2   =   LibWrap.TestRefArrayOfInts(   ref   buffer,   ref   size   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum2   ); 
            if(   size   >   0   ) 
            { 
                  int[]   arrayRes   =   new   int[   size   ]; 
                  Marshal.Copy(   buffer,   arrayRes,   0,   size   ); 
                  Marshal.FreeCoTaskMem(   buffer   ); 
                  Console.WriteLine(   "\nInteger   array   passed   ByRef   after   call: "   ); 
                  foreach(   int   i   in   arrayRes   ) 
                  { 
                        Console.Write(   "   "   +   i   ); 
                  } 
            } 
            else 
                  Console.WriteLine(   "\nArray   after   call   is   empty "   ); 
                  
            //   matrix   ByVal   
            const   int   DIM   =   5; 
            int[,]   matrix   =   new   int[   DIM,   DIM   ]; 
            
            Console.WriteLine(   "\n\nMatrix   before   call: "   ); 
            for(   int   i   =   0;   i   <   DIM;   i++   ) 
            { 
                  for(   int   j   =   0;   j   <   DIM;   j++   ) 
                  { 
                        matrix[   i,   j   ]   =   j; 
                        Console.Write(   "   "   +   matrix[   i,   j   ]   ); 
                  } 
                  Console.WriteLine(   " "   ); 
            } 
            int   sum3   =   LibWrap.TestMatrixOfInts(   matrix,   DIM   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum3   ); 
            Console.WriteLine(   "\nMatrix   after   call: "   ); 
            for(   int   i   =   0;   i   <   DIM;   i++   ) 
            { 
                  for(   int   j   =   0;   j   <   DIM;   j++   ) 
                  { 
                        Console.Write(   "   "   +   matrix[   i,   j   ]   ); 
                  } 
                  Console.WriteLine(   " "   ); 
            } 
            
            //   string   array   ByVal   
            String[]   strArray   =   {   "one ",   "two ",   "three ",   "four ",   "five "   }; 
            Console.WriteLine(   "\n\nString   array   before   call: "   ); 
            foreach(   String   s   in   strArray   ) 
                  Console.Write(   "   "+   s   ); 
            int   lenSum   =   LibWrap.TestArrayOfStrings(   strArray,   strArray.Length   ); 
            Console.WriteLine(   "\nSum   of   string   lengths: "   +   lenSum   ); 
            Console.WriteLine(   "\nString   array   after   call: "   ); 
            foreach(   String   s   in   strArray   ) 
            { 
                  Console.Write(   "   "   +   s   ); 
            }       
            
            //   struct   array   ByVal   
            MyPoint[]   points   =   {   new   MyPoint(1,1),   new   MyPoint(2,2),   new   MyPoint(3,3)   }; 
            Console.WriteLine(   "\n\nPoints   array   before   call: "   ); 
            foreach(   MyPoint   p   in   points   ) 
                  Console.WriteLine(   "x   =   {0},   y   =   {1} ",   p.x,   p.y   ); 
            int   allSum   =   LibWrap.TestArrayOfStructs(   points,   points.Length   ); 
            Console.WriteLine(   "\nSum   of   points: "   +   allSum   ); 
            Console.WriteLine(   "\nPoints   array   after   call: "   ); 
            foreach(   MyPoint   p   in   points   ) 
                  Console.WriteLine(   "x   =   {0},   y   =   {1} ",   p.x,   p.y   );             
                  
            //   struct   with   strings   array   ByVal   
            MyPerson[]   persons   =   {   new   MyPerson(   "Kim ",   "Akers "   ),   
            new   MyPerson(   "Adam ",   "Barr "   ),   new   MyPerson(   "Jo ",   "Brown "   )}; 
            
            Console.WriteLine(   "\n\nPersons   array   before   call: "   ); 
            foreach(   MyPerson   pe   in   persons   ) 
                Console.WriteLine(   "first   =   {0},   last   =   {1} ",   pe.first,   pe.last   ); 
            int   namesSum   =   LibWrap.TestArrayOfStructs2(   persons,   persons.Length   ); 
            Console.WriteLine(   "\nSum   of   name   lengths: "   +   namesSum   ); 
            Console.WriteLine(   "\n\nPersons   array   after   call: "   ); 
            foreach(   MyPerson   pe   in   persons   ) 
                Console.WriteLine(   "first   =   {0},   last   =   {1} ",   pe.first,   pe.last   ); 
      } 


#1


C#需要声明
类似
从 Kernel32.dll 导出的 GetSystemTime。 
VOID GetSystemTime(LPSYSTEMTIME lpSystemTime);
传递到该函数的初始结构包含以下元素:
typedef struct _SYSTEMTIME { 
    WORD wYear; 
    WORD wMonth; 
    WORD wDayOfWeek; 
    WORD wDay; 
    WORD wHour; 
    WORD wMinute; 
    WORD wSecond; 
    WORD wMilliseconds; 
} SYSTEMTIME, *PSYSTEMTIME;
在该示例中,SystemTime 类包含表示为类成员的原始结构的元素。StructLayoutAttribute 属性经过设置,以确保成员在内存中按它们的出现顺序依次排列。
LibWrap 类包含 GetSystemTime 方法的托管原型,默认情况下,它将 SystemTime 类作为 In/Out 参数进行传递。必须用 InAttribute 和 OutAttribute 属性声明该参数,因为作为引用类型的类在默认情况下将作为输入参数进行传递。为使调用方接收结果,必须显式应用这些方向属性。App 类创建 SystemTime 类的一个新实例,然后访问其数据字段。
声明原型
[Visual Basic]
' Declares a class member for each structure element.
< StructLayout(LayoutKind.Sequential )> _
Public Class SystemTime
   Public year As Short
   ...
   Public milliseconds As Short 
End Class 'SystemTime

Public Class LibWrap
   ' Declares a managed prototype for the unmanaged function.
   Declare Sub GetSystemTime Lib "Kernel32.dll" ( <[In], Out> ByVal st _
      As SystemTime )
End Class 'LibWrap
[C#]
// Declares a class member for each structure element.
[ StructLayout( LayoutKind.Sequential )]
public class SystemTime 
{
   public ushort year; 
   ... 
   public ushort milliseconds; 
}

public class LibWrap 
{
   // Declares a managed prototype for the unmanaged function.
   [ DllImport( "Kernel32.dll" )]
   public static extern void GetSystemTime( [In,Out] SystemTime st );
}
调用函数
[Visual Basic]
Public Class App
   Public Shared Sub Main()
      Dim st As New SystemTime()
      LibWrap.GetSystemTime( st )
      Console.Write( "The Date and Time is: " )
      ...
   End Sub 'Main
End Class 'App
[C#]
public class App
{
   public static void Main()
   {
      SystemTime st = new SystemTime();
      LibWrap.GetSystemTime( st );
      Console.Write( "The Date and Time is: " );
      ...
   }
}

#2


谢谢。我是想传递结构体数组进dll。
dll原形HRESULT Add(struct Struct_data* datatag,int num);
num为结构体数组长度

#3


IntPtr Add([MarshalAs(UnManagedType.LPArray)]Struct_data[] datatag,int num);

#4


谢谢,我试试

#5


我在C#中怎么是Add(ref Struct_data datatag,int num);
如何改为IntPtr Add([MarshalAs(UnManagedType.LPArray)]Struct_data[] datatag,int num);

#6


MARK
学习

#7


再给你一段代码,直接抄msdn的
[ StructLayout( LayoutKind.Sequential )]
public struct MyPoint 
{
   public int x; 
   public int y;
   public MyPoint( int x, int y )
   {
      this.x = x;
      this.y = y;
   }
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyPerson 
{
   public String first; 
   public String last;
   public MyPerson( String first, String last )
   {
      this.first = first;
      this.last = last;
   }
}

public class LibWrap
{
   // Declares a managed prototype for an array of integers by value.
   // The array size cannot be changed, but the array is copied back.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfInts([In, Out] int[] array, int size );
   
   // Declares a managed prototype for an array of integers by reference.
   // The array size can change, but the array is not copied back 
   // automatically because the marshaler does not know the resulting size.
   // The copy must be performed manually.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestRefArrayOfInts( ref IntPtr array, 
      ref int size );
   
   // Declares a managed prototype for a matrix of integers by value.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestMatrixOfInts([In, Out] int[,] pMatrix, 
      int row );   
   // Declares a managed prototype for an array of strings by value.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStrings( [In, Out] 
      String[] stringArray, int size );
   
   // Declares a managed prototype for an array of structures with integers.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStructs([In, Out] MyPoint[] 
      pointArray, int size ); 
   
   // Declares a managed prototype for an array of structures with strings.
   [ DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern int TestArrayOfStructs2( [In, Out] 
      MyPerson[] personArray, int size );
}
调用函数
[C#]
public class App
{
   public static void Main()
   {
      // array ByVal 
      int[] array1 = new int[ 10 ];
      Console.WriteLine( "Integer array passed ByVal before call:" );
      for( int i = 0; i < array1.Length; i++ )
      {
         array1[ i ] = i;
         Console.Write( " " + array1[ i ] );
      }
      int sum1 = LibWrap.TestArrayOfInts( array1, array1.Length );
      Console.WriteLine( "\nSum of elements:" + sum1 );
      Console.WriteLine( "\nInteger array passed ByVal after call:" );
      
      foreach( int i in array1 )
      {
         Console.Write( " " + i );
      }   
      
      // array ByRef 
      int[] array2 = new int[ 10 ];
      int size = array2.Length;
      Console.WriteLine( "\n\nInteger array passed ByRef before call:" );
      for( int i = 0; i < array2.Length; i++ )
      {
         array2[ i ] = i;
         Console.Write( " " + array2[ i ] );
      }
      IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf( size ) 
         * array2.Length );
      Marshal.Copy( array2, 0, buffer, array2.Length );
      
      int sum2 = LibWrap.TestRefArrayOfInts( ref buffer, ref size );
      Console.WriteLine( "\nSum of elements:" + sum2 );
      if( size > 0 )
      {
         int[] arrayRes = new int[ size ];
         Marshal.Copy( buffer, arrayRes, 0, size );
         Marshal.FreeCoTaskMem( buffer );
         Console.WriteLine( "\nInteger array passed ByRef after call:" );
         foreach( int i in arrayRes )
         {
            Console.Write( " " + i );
         }
      }
      else
         Console.WriteLine( "\nArray after call is empty" );
         
      // matrix ByVal 
      const int DIM = 5;
      int[,] matrix = new int[ DIM, DIM ];
      
      Console.WriteLine( "\n\nMatrix before call:" );
      for( int i = 0; i < DIM; i++ )
      {
         for( int j = 0; j < DIM; j++ )
         {
            matrix[ i, j ] = j;
            Console.Write( " " + matrix[ i, j ] );
         }
         Console.WriteLine( "" );
      }
      int sum3 = LibWrap.TestMatrixOfInts( matrix, DIM );
      Console.WriteLine( "\nSum of elements:" + sum3 );
      Console.WriteLine( "\nMatrix after call:" );
      for( int i = 0; i < DIM; i++ )
      {
         for( int j = 0; j < DIM; j++ )
         {
            Console.Write( " " + matrix[ i, j ] );
         }
         Console.WriteLine( "" );
      }
      
      // string array ByVal 
      String[] strArray = { "one", "two", "three", "four", "five" };
      Console.WriteLine( "\n\nString array before call:" );
      foreach( String s in strArray )
         Console.Write( " "+ s );
      int lenSum = LibWrap.TestArrayOfStrings( strArray, strArray.Length );
      Console.WriteLine( "\nSum of string lengths:" + lenSum );
      Console.WriteLine( "\nString array after call:" );
      foreach( String s in strArray )
      {
         Console.Write( " " + s );
      }   
      
      // struct array ByVal 
      MyPoint[] points = { new MyPoint(1,1), new MyPoint(2,2), new MyPoint(3,3) };
      Console.WriteLine( "\n\nPoints array before call:" );
      foreach( MyPoint p in points )
         Console.WriteLine( "x = {0}, y = {1}", p.x, p.y );
      int allSum = LibWrap.TestArrayOfStructs( points, points.Length );
      Console.WriteLine( "\nSum of points:" + allSum );
      Console.WriteLine( "\nPoints array after call:" );
      foreach( MyPoint p in points )
         Console.WriteLine( "x = {0}, y = {1}", p.x, p.y );      
         
      // struct with strings array ByVal 
      MyPerson[] persons = { new MyPerson( "Kim", "Akers" ), 
      new MyPerson( "Adam", "Barr" ), new MyPerson( "Jo", "Brown" )};
      
      Console.WriteLine( "\n\nPersons array before call:" );
      foreach( MyPerson pe in persons )
        Console.WriteLine( "first = {0}, last = {1}", pe.first, pe.last );
      int namesSum = LibWrap.TestArrayOfStructs2( persons, persons.Length );
      Console.WriteLine( "\nSum of name lengths:" + namesSum );
      Console.WriteLine( "\n\nPersons array after call:" );
      foreach( MyPerson pe in persons )
        Console.WriteLine( "first = {0}, last = {1}", pe.first, pe.last );
   }
}

#8


根本不会

我还是循序渐进把

#9


必须用dllimport吗?我直接引用的。

#10


c++ dll
是什么类型的dll 

win32 的
还是com的
还是托管的
???

#11


com的

#12


你可以把结构体封装成COM对象,然后传递结构体的接口

#13


能说具体点吗?不明白

#14


http://msdn2.microsoft.com/en-us/library/4h56szat(VS.80).aspx

#15


看着不舒服,整理下看

[   StructLayout(   LayoutKind.Sequential   )] 
public   struct   MyPoint   

      public   int   x;   
      public   int   y; 
      public   MyPoint(   int   x,   int   y   ) 
      { 
            this.x   =   x; 
            this.y   =   y; 
      } 

[   StructLayout(   LayoutKind.Sequential,   CharSet=CharSet.Ansi   )] 
public   struct   MyPerson   

      public   String   first;   
      public   String   last; 
      public   MyPerson(   String   first,   String   last   ) 
      { 
            this.first   =   first; 
            this.last   =   last; 
      } 


public   class   LibWrap 

      //   Declares   a   managed   prototype   for   an   array   of   integers   by   value. 
      //   The   array   size   cannot   be   changed,   but   the   array   is   copied   back. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfInts([In,   Out]   int[]   array,   int   size   ); 
      
      //   Declares   a   managed   prototype   for   an   array   of   integers   by   reference. 
      //   The   array   size   can   change,   but   the   array   is   not   copied   back   
      //   automatically   because   the   marshaler   does   not   know   the   resulting   size. 
      //   The   copy   must   be   performed   manually. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestRefArrayOfInts(   ref   IntPtr   array,   
            ref   int   size   ); 
      
      //   Declares   a   managed   prototype   for   a   matrix   of   integers   by   value. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestMatrixOfInts([In,   Out]   int[,]   pMatrix,   
            int   row   );       
      //   Declares   a   managed   prototype   for   an   array   of   strings   by   value. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStrings(   [In,   Out]   
            String[]   stringArray,   int   size   ); 
      
      //   Declares   a   managed   prototype   for   an   array   of   structures   with   integers. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStructs([In,   Out]   MyPoint[]   
            pointArray,   int   size   );   
      
      //   Declares   a   managed   prototype   for   an   array   of   structures   with   strings. 
      [   DllImport(   "..\\LIB\\PinvokeLib.dll "   )] 
      public   static   extern   int   TestArrayOfStructs2(   [In,   Out]   
            MyPerson[]   personArray,   int   size   ); 

调用函数 
[C#] 
public   class   App 

      public   static   void   Main() 
      { 
            //   array   ByVal   
            int[]   array1   =   new   int[   10   ]; 
            Console.WriteLine(   "Integer   array   passed   ByVal   before   call: "   ); 
            for(   int   i   =   0;   i   <   array1.Length;   i++   ) 
            { 
                  array1[   i   ]   =   i; 
                  Console.Write(   "   "   +   array1[   i   ]   ); 
            } 
            int   sum1   =   LibWrap.TestArrayOfInts(   array1,   array1.Length   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum1   ); 
            Console.WriteLine(   "\nInteger   array   passed   ByVal   after   call: "   ); 
            
            foreach(   int   i   in   array1   ) 
            { 
                  Console.Write(   "   "   +   i   ); 
            }       
            
            //   array   ByRef   
            int[]   array2   =   new   int[   10   ]; 
            int   size   =   array2.Length; 
            Console.WriteLine(   "\n\nInteger   array   passed   ByRef   before   call: "   ); 
            for(   int   i   =   0;   i   <   array2.Length;   i++   ) 
            { 
                  array2[   i   ]   =   i; 
                  Console.Write(   "   "   +   array2[   i   ]   ); 
            } 
            IntPtr   buffer   =   Marshal.AllocCoTaskMem(   Marshal.SizeOf(   size   )   
                  *   array2.Length   ); 
            Marshal.Copy(   array2,   0,   buffer,   array2.Length   ); 
            
            int   sum2   =   LibWrap.TestRefArrayOfInts(   ref   buffer,   ref   size   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum2   ); 
            if(   size   >   0   ) 
            { 
                  int[]   arrayRes   =   new   int[   size   ]; 
                  Marshal.Copy(   buffer,   arrayRes,   0,   size   ); 
                  Marshal.FreeCoTaskMem(   buffer   ); 
                  Console.WriteLine(   "\nInteger   array   passed   ByRef   after   call: "   ); 
                  foreach(   int   i   in   arrayRes   ) 
                  { 
                        Console.Write(   "   "   +   i   ); 
                  } 
            } 
            else 
                  Console.WriteLine(   "\nArray   after   call   is   empty "   ); 
                  
            //   matrix   ByVal   
            const   int   DIM   =   5; 
            int[,]   matrix   =   new   int[   DIM,   DIM   ]; 
            
            Console.WriteLine(   "\n\nMatrix   before   call: "   ); 
            for(   int   i   =   0;   i   <   DIM;   i++   ) 
            { 
                  for(   int   j   =   0;   j   <   DIM;   j++   ) 
                  { 
                        matrix[   i,   j   ]   =   j; 
                        Console.Write(   "   "   +   matrix[   i,   j   ]   ); 
                  } 
                  Console.WriteLine(   " "   ); 
            } 
            int   sum3   =   LibWrap.TestMatrixOfInts(   matrix,   DIM   ); 
            Console.WriteLine(   "\nSum   of   elements: "   +   sum3   ); 
            Console.WriteLine(   "\nMatrix   after   call: "   ); 
            for(   int   i   =   0;   i   <   DIM;   i++   ) 
            { 
                  for(   int   j   =   0;   j   <   DIM;   j++   ) 
                  { 
                        Console.Write(   "   "   +   matrix[   i,   j   ]   ); 
                  } 
                  Console.WriteLine(   " "   ); 
            } 
            
            //   string   array   ByVal   
            String[]   strArray   =   {   "one ",   "two ",   "three ",   "four ",   "five "   }; 
            Console.WriteLine(   "\n\nString   array   before   call: "   ); 
            foreach(   String   s   in   strArray   ) 
                  Console.Write(   "   "+   s   ); 
            int   lenSum   =   LibWrap.TestArrayOfStrings(   strArray,   strArray.Length   ); 
            Console.WriteLine(   "\nSum   of   string   lengths: "   +   lenSum   ); 
            Console.WriteLine(   "\nString   array   after   call: "   ); 
            foreach(   String   s   in   strArray   ) 
            { 
                  Console.Write(   "   "   +   s   ); 
            }       
            
            //   struct   array   ByVal   
            MyPoint[]   points   =   {   new   MyPoint(1,1),   new   MyPoint(2,2),   new   MyPoint(3,3)   }; 
            Console.WriteLine(   "\n\nPoints   array   before   call: "   ); 
            foreach(   MyPoint   p   in   points   ) 
                  Console.WriteLine(   "x   =   {0},   y   =   {1} ",   p.x,   p.y   ); 
            int   allSum   =   LibWrap.TestArrayOfStructs(   points,   points.Length   ); 
            Console.WriteLine(   "\nSum   of   points: "   +   allSum   ); 
            Console.WriteLine(   "\nPoints   array   after   call: "   ); 
            foreach(   MyPoint   p   in   points   ) 
                  Console.WriteLine(   "x   =   {0},   y   =   {1} ",   p.x,   p.y   );             
                  
            //   struct   with   strings   array   ByVal   
            MyPerson[]   persons   =   {   new   MyPerson(   "Kim ",   "Akers "   ),   
            new   MyPerson(   "Adam ",   "Barr "   ),   new   MyPerson(   "Jo ",   "Brown "   )}; 
            
            Console.WriteLine(   "\n\nPersons   array   before   call: "   ); 
            foreach(   MyPerson   pe   in   persons   ) 
                Console.WriteLine(   "first   =   {0},   last   =   {1} ",   pe.first,   pe.last   ); 
            int   namesSum   =   LibWrap.TestArrayOfStructs2(   persons,   persons.Length   ); 
            Console.WriteLine(   "\nSum   of   name   lengths: "   +   namesSum   ); 
            Console.WriteLine(   "\n\nPersons   array   after   call: "   ); 
            foreach(   MyPerson   pe   in   persons   ) 
                Console.WriteLine(   "first   =   {0},   last   =   {1} ",   pe.first,   pe.last   ); 
      }