Chinaunix首页 | 论坛 | 博客
  • 博客访问: 588108
  • 博文数量: 141
  • 博客积分: 3425
  • 博客等级: 中校
  • 技术积分: 1609
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-23 15:55
文章分类

全部博文(141)

文章存档

2019年(5)

2011年(19)

2010年(36)

2009年(13)

2008年(50)

2007年(18)

分类:

2010-05-12 17:16:25

该示例说明如何使用从非托管函数返回的字符串,以及如何传递包含 Unicode 格式或 ANSI 格式的字符串的结构。它还显示如何正确地初始化这些字符串以及如何检索返回值。

String 示例使用以下非托管函数(这里同时显示其原始函数声明):

从 PinvokeLib.dll 导出的 TestStringAsResult。

char* TestStringAsResult();

char* TestStringAsResult();

从 PinvokeLib.dll 导出的 TestStringInStruct。

void TestStringInStruct(MYSTRSTRUCT* pStruct);

void TestStringInStruct(MYSTRSTRUCT* pStruct);

从 PinvokeLib.dll 导出的 TestStringInStructAnsi。

void TestStringInStructAnsi(MYSTRSTRUCT2* pStruct);

void TestStringInStructAnsi(MYSTRSTRUCT2* pStruct);

PinvokeLib.dll 是一个自定义非托管库,它包含前面列出的函数的实现以及两种结构 MYSTRSTRUCT 和 MYSTRSTRUCT2。这些结构包含以下元素:

typedef struct _MYSTRSTRUCT
{
wchar_t* buffer;
UINT size;
} MYSTRSTRUCT;
typedef struct _MYSTRSTRUCT2
{
char* buffer;
UINT size;
} MYSTRSTRUCT2;

typedef struct _MYSTRSTRUCT
{
wchar_t* buffer;
UINT size;
} MYSTRSTRUCT;
typedef struct _MYSTRSTRUCT2
{
char* buffer;
UINT size;
} MYSTRSTRUCT2;

在此示例中,托管 MyStrStruct 和 MyStrStruct2 结构包含托管字符串而不是 StringBuilder 缓冲区,原因是 StringBuilder 类型不能在结构内部使用。StructLayoutAttribute 属性经过设置,可确保成员在内存中按它们的出现顺序依次排列。CharSet 字段经过设置以指定 ANSI 或 Unicode 格式。

LibWrap 类包含由 App 类调用的托管原型方法。虽然结构通常是通过值传递的,但 TestStringInStruct 和 TestStringInStructAnsi 方法的参数使用 ref(在 Visual Basic 中为 ByRef)关键字来标记,该关键字通过引用传递结构。

下面的代码示例的源代码由 .NET Framework 平台调用技术示例提供。


声明原型
// Declares a managed structure for each unmanaged structure.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Unicode )]
public struct MyStrStruct
{
public String buffer;
public int size;
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyStrStruct2
{
public String buffer;
public int size;
}
public class LibWrap
{
// Declares managed prototypes for unmanaged functions.
[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern String TestStringAsResult();

[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestStringInStruct( ref MyStrStruct mss );

[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestStringInStructAnsi( ref MyStrStruct2
mss );
}

// Declares a managed structure for each unmanaged structure.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Unicode )]
public struct MyStrStruct
{
public String buffer;
public int size;
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyStrStruct2
{
public String buffer;
public int size;
}
public class LibWrap
{
// Declares managed prototypes for unmanaged functions.
[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern String TestStringAsResult();

[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestStringInStruct( ref MyStrStruct mss );

[DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestStringInStructAnsi( ref MyStrStruct2
mss );

}


调用函数

public class App
{
public static void Main()
{
// String as result.
String str = LibWrap.TestStringAsResult();
Console.WriteLine( "\nString returned: {0}", str );

// Initializes buffer and appends something to the end so the whole
// buffer is passed to the unmanaged side.
StringBuilder buffer = new StringBuilder( "content", 100 );
buffer.Append( (char)0 );
buffer.Append( '*', buffer.Capacity - 8 );

MyStrStruct mss;
mss.buffer = buffer.ToString();
mss.size = mss.buffer.Length;

LibWrap.TestStringInStruct( ref mss );
Console.WriteLine( "\nBuffer after Unicode function call: {0}",
mss.buffer );

StringBuilder buffer2 = new StringBuilder( "content", 100 );
buffer2.Append( (char)0 );
buffer2.Append( '*', buffer2.Capacity - 8 );

MyStrStruct2 mss2;
mss2.buffer = buffer2.ToString();
mss2.size = mss2.buffer.Length;

LibWrap.TestStringInStructAnsi( ref mss2 );
Console.WriteLine( "\nBuffer after Ansi function call: {0}",
mss2.buffer );
}
}
阅读(1028) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~