Windows Mobile和Wince(Windows Embedded CE)下如何封装Native DLL提供给.NET Compact Framework进行调用

简介:

背景

在Windows Mobile和Wince(Windows Embedded CE)产品开发中,有时候会使用C++封装一些共用代码,例如在我们项目中使用了C++封装了一个对USB通信的公开代码库,这些共用代码编译成静态库,其他模式使用的时候,只需要include头文件,链接lib库就可以了,但是.NET Compact Framework的程序没有办法使用C++编译的静态库,所以产生封装Native DLL提供给.NET Compact Framework程序调用的需求。

 

简介

本文讲述在Windows Mobile和Wince(Windows Embedded CE)下如何封装Native DLL提供给.NET Compact Framework进行调用。

 

可选方案

在.NET framework下可以把C++编译成托管的DLL,这样.NET的程序可以直接调用这个DLL了,但是在.NET Compact Framework下,不支持managed c++,所以只能封装成Native的DLL,然后.NET Compact Framework P/Invoke该Native DLL。 封装Native的DLL有两个可选的方案。

 

方案一: .DEF文件

使用.DEF文件,.DEF文件可以定义输出接口

LIBRARY   NativeLib
EXPORTS
Insert @1
Delete @2
Member @3
Min @4

上面的.def文件定义了四个输出接口。如果使用.def文件,需要在编译选项进行配置,如下图:

native_dll2

使用.def文件麻烦的地方是每次更新接口都要手工更新.def文件,但是使用.def文件有一个好处是当dll发生更新以后,如果定义的ordinal没有发生改变的话,调用方不需要重新链接程序就可以使用新的DLL,Windows Mobile的今日组件就是使用.def文件进行定义的,需要实现ordinal为240和241两个接口:

InitializeCustomItem        @240    NONAME
CustomItemOptionsDlgProc @241 NONAME

这样shell32进程就可以加载实现了这两个接口的DLL,不需要重新连接来支持新的组件。

 

方案二: __declspec(dllexport)

我个人偏向于使用__declspec(dllexport)的方案,因为P/Invoke不存在调用方重新链接的问题,所以我偏向于使用__declspec(dllexport)的方案。

使用__declspec(dllexport)的方案,在需要输出的函数加入__declspec(dllexport)。这样该函数就会生成输出表。

#define EXPORT_API __declspec(dllexport)
EXPORT_API BOOL OpenIndicator()
{
return TRUE;
}

例如上述定义生成以下输出。使用Dumpbin /exports进行查看。

Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file NativeLib.dll

File Type: DLL

Section contains the following exports for NativeLib.dll

00000000 characteristics
4AF757EA time date stamp Sun Nov 08 10:44:42 2009
0.00 version
1 ordinal base
1 number of functions
1 number of names

ordinal hint RVA name

1 0 0000BA30 ?OpenIndicator@@YAHXZ = ?OpenIndicator@@YAHXZ (int __c
decl OpenIndicator(void))

Summary

1000 .data
2000 .pdata
2000 .rdata
2000 .reloc
19000 .text

有没有发现输出是?OpenIndicator@@YAHXZ 而不是 OpenIndicator。

如果.NET Compact Framework的调用方如下:

[System.Runtime.InteropServices.DllImport("DeviceCommsLib.dll", SetLastError = true]
private static extern bool OpenIndicator();

程序执行的时候会抛出找不到入口点的异常,如下图:

native_dll1

原因是生成输出的时候使用C++的命名输出了?OpenIndicator@@YAHXZ 而不是 OpenIndicator。如果要解决这个问题,有两个办法:方法一,在调用方指定入口点:

[System.Runtime.InteropServices.DllImport("DeviceCommsLib.dll", SetLastError = true, EntryPoint = "?OpenIndicator@@YAHXZ")]
private static extern bool OpenIndicator();
这个办法不好,因为调用方需要使用Dumpbin /exports查看输出入口点。

 

 

 

方法二,增加extern "C",如下:

#define EXPORT_API __declspec(dllexport)
extern "C" {
EXPORT_API bool OpenIndicator()
{
return true;
}
}

这样使用了C的命名,使用Dumpbin /exports查看输出如下:

Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file NativeLib.dll

File Type: DLL

Section contains the following exports for NativeLib.dll

00000000 characteristics
4AF75999 time date stamp Sun Nov 08 10:51:53 2009
0.00 version
1 ordinal base
1 number of functions
1 number of names

ordinal hint RVA name

1 0 0000BA30 OpenIndicator = OpenIndicator

Summary

1000 .data
2000 .pdata
2000 .rdata
2000 .reloc
19000 .text

输出接口变成OpenIndicator 了。

 

总结

总结一下,如果有Native C++的共用静态库需要提供给.NET Compact Framework调用,首先新建一个win32的DLL,把改静态库链接到这个DLL里面,然后定义DLL通过extern "C" __declspec(dllexport来输出出接口,最后在.NET Compact Framework程序就可以通过P/Invoke来调用原先在静态库中的功能模块来。

关于P/Invoke,我原先写过些文章可以参考。

.NET Compact Framework 下Win32 API P/Invoke 的使用

开发P/Invoke的工具与Website



    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2009/11/09/Windows_Mobile_Native_DLL.html,如需转载请自行联系原作者



相关文章
|
2月前
|
区块链 C# Windows
PasteEx:一款.NET开源的Windows快捷粘贴神器
PasteEx:一款.NET开源的Windows快捷粘贴神器
57 17
|
2月前
|
Web App开发 C# Windows
一款.NET开源的Windows资源管理器标签页工具
一款.NET开源的Windows资源管理器标签页工具
|
2月前
|
弹性计算 开发框架 安全
基于云效 Windows 构建环境和 Nuget 制品仓库进行 .Net 应用开发
本文将基于云效 Flow 流水线 Windows 构建环境和云效 Packages Nuget 制品仓库手把手教你如何开发并部署一个 .NET 应用,从环境搭建到实战应用发布的详细教程,帮助你掌握 .NET 开发的核心技能。
|
3月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
|
3月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(下)
本文接续前文,深入讲解了在Windows环境下使用C#和ADO.NET操作南大通用GBase 8s数据库的方法。通过Visual Studio 2022创建项目,添加GBase 8s的DLL引用,并提供了详细的C#代码示例,涵盖数据库连接、表的创建与修改、数据的增删查改等操作,旨在帮助开发者提高数据库管理效率。
|
Windows
WINDOWS下获得DLL所在目录的代码
WINDOWS下获得DLL所在目录的代码
156 0
|
Windows
WINDOWS下获得DLL所在目录的代码
WINDOWS下获得DLL所在目录的代码
120 0
|
2天前
|
安全 网络安全 数据安全/隐私保护
Windows Server 2025 Active Directory 重置用户密码
密码重置是管理员日常任务之一,用户因忘记或多次输错密码导致账户锁定时需进行重置。本文介绍在Active Directory服务器上重置密码的三种方法。
|
2月前
|
安全 关系型数据库 MySQL
Windows Server 安装 MySQL 8.0 详细指南
安装 MySQL 需要谨慎,特别注意安全配置和权限管理。根据实际业务需求调整配置,确保数据库的性能和安全。
232 9
|
3月前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。
217 4

热门文章

最新文章