UML软件工程组织

为基于 Microsoft .NET Framework 精简版的应用程序编写非托管函数
Content Master Ltd(选自微软中国)
适用于:
    Microsoft® .NET Framework 精简版 1.0
    Microsoft Visual Studio® .NET 2003
    Microsoft eMbedded Visual C++® 3.0

摘要:学习如何创建可通过平台调用在智能设备应用程序中使用的非托管函数。

目录

简介

编写 Microsoft .NET Framework 精简版应用程序时,有时需要调用非托管代码,才能直接与底层操作系统进行交互。.NET Framework 精简版中的非托管代码和托管代码之间的互操作性是 .NET Framework 完整版的子集。例如,.NET Framework 精简版不支持将代理用作回调函数。同样,.NET Framework 精简版也不支持完整的 COM 互操作性,因此,如果要在 .NET Framework 精简版中访问 COM 对象,必须编写非托管模块以将其作为包装程序,这样才能处理对 COM 对象和类型封送处理的调用。

编写从托管环境调用的非托管代码时,有几个问题需多加注意。本文介绍了这些注意事项,并提供了非托管动态链接库 (DLL) 的代码。

本文假定您熟悉 eMbedded Visual C++ 开发环境并了解 C++ 语言。

选择 eMbedded Visual C++ 3.0 项目类型

使用 eVC++ 时,您可以选择使用 WCE 动态链接库项目类型,也可以选择 WCE MFC 应用程序向导 (dll) 项目类型。前者用于简单的 DLL 项目,后者用于需要 Microsoft 基础类 (MFC) 功能的项目。为了说明有关开发在 .NET Framework 精简版中使用的非托管 DLL 的要点,本文将介绍如何使用 WCE 动态链接库项目类型。

托管代码只需要编译一次,就可以在安装了 .NET Framework 精简版运行时的任何移动设备上运行;非托管代码与之不同,必须为要支持的每个硬件平台编译单独的 DLL。在新建项目对话框中,必须选择希望在 DLL 中支持的处理器,eVC++ 将为每个选定的处理器平台编译单独的 DLL。eVC++ 编译器能够支持各种处理器,包括 ARM、MIPS、SH 和 x86。必须记住,要在模拟器中使用 DLL,您可能需要创建 Intel x86 版本的 DLL。

导出入口点

可以从 DLL 外部调用的任何函数都必须标记为导出函数。在 eVC++ 中,这可以通过为函数声明添加 _declspec(dllexport) 前缀来实现。此外,按照 WINAPI 调用约定来标记函数声明也很有用,因为这是 .NET Framework 精简版所支持的唯一调用约定。WINAPI 宏映射到 __cdecl 调用约定。同样,在 .NET Framework 精简版中,CallingConvention.Winapi 等同于托管的 WINAPI

以下示例显示了使用以上技术时 eVC++ 中的函数声明的外观:

_declspec(dllexport) int WINAPI MyFunction(int MyVal)
{
    // 在此处添加实现代码
    return 0;
}

从托管代码中调用此代码时,要按照以下格式声明代码中的非托管函数:

[DllImport("NativeDll.dll",EntryPoint="MyFunction")]
public static extern int MyFunction(int MyVal);

遗憾的是,由于“名称混成”的原因,此调用无法按照预期的方式进行。

处理 C++ 名称混成

在 Windows 的早期版本中,对象文件格式无法处理重载函数。为解决此问题,编译器根据函数名称和参数列表为每个函数生成一个唯一名称。这样就确保了每个函数对链接器都有一个唯一的名称。这种生成唯一名称的方法就叫做“名称混成”。MyFunction 的混成形式类似于 ?MyFunction@@YAJXZ

名称混成为要调用非托管代码的托管代码带来一个问题。每个编译器以不同的方式处理混成,因此很难了解导出入口点的确切名称。在 C++ 中,可以使用 extern "C" 声明强制编译器不进行名称混成,而是使导出函数的名称与源代码中的函数名称相匹配。

使用 extern "C" 声明时,C++ 函数示例如下所示:

extern "C" _declspec(dllexport) int WINAPI multiply(int n1, int n2) 
{ 
    // 返回 n1 和 n2 相乘后的值
    return(n1 * n2)
}

类型封送处理

.NET Framework 精简版支持托管代码与非托管代码之间的简单类型转换。有些类型不需要任何转换,这些类型称为“通用类型”。下表显示了可通用类型及其托管和非托管的等价类型。

C# Visual Basic .NET Native C/C++
Int Integer int
short Short short
bool Boolean BYTE
char Char WCHAR

此外,您还可以将数组、结构和类传递给非托管代码。

更多信息

有关更多信息,请参阅以下资源:

 

 

版权所有:UML软件工程组织