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: " );
...
}
}
类似
从 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为结构体数组长度
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);
如何改为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 );
}
}
[ 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的
还是托管的
???
是什么类型的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: " );
...
}
}
类似
从 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为结构体数组长度
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);
如何改为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 );
}
}
[ 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的
还是托管的
???
是什么类型的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 );
}
}