使用Visual Studio 2005创建C#项目案例

开发 后端
这是一篇使用Visual Studio 2005创建C#项目案例,和.NET Framework一样,.NET Compact Framework也提供了平台调用P/Invoke功能以支持托管代码调用驻留于 DLL 中的非托管函数。关于.NET Compact Framework的详细讨论。

本C#项目案例主要是使用Visual Studio 2005创建C++和C#混合项目的方法,涉及C#智能设备项目和C++智能设备项目。

通过P/Invoke我们可以充分利用已有的非托管资源,使用非托管的系统API函数,以弥补.NET Compact Framework的不完备性。因此我们可以使用C++来编写非托管的DLL函数,然后通过P/Invoke在C#中进行调用。vs2005提供了一个很好的集成环境,我们可以使用一个解决方案同时管理托管的C#项目和非托管的C++项目。下面介绍使用vs2005创建C++和C#混合项目的方法。

1、首先创建一个C#智能设备项目。如智能设备-Pockent PC 2003-设备应用程序,假定解决方案名为“MixedSolution”,项目名为“DeviceApplication1”。

2、添加C++智能设备项目。在解决方案“MixedSolution”中添加一个新的项目,使用C++创建相同平台(如Pockent PC 200)的智能设备Win32或MFC项目,假定项目名为“CppProject”。注意CppProject必须是Win32或MFC的DLL项目,因为我们需要使用P/Invoke功能实现由C#调用C++项目的DLL。在C++项目中编写需要的函数处理后,对要导出的函数需要进行导出定义,该函数将被C#的P/Invoke调用,只有被正确导出的函数才能被P/Invoke识别。这里值得注意的只有使用修饰符extern “C” _declspec(dllexport)修饰的函数才能被P/Invoke调用。在该修饰符中_declspec(DLLexport)表示输出,即导出函数的定义;extern “C”表示该函数使用C编译方式,可以被C调用,P/Invoke只能调用使用这种方式编译的函数。

我们可以定义如下符号:

  1. #define DLLAPI extern "C" __declspec(dllexport) 

定义了该符号后,可以使用它来修饰要导出的函数,如声明函数MyFunction:

  1. DLLAPI int MyFunction(int, int); 

声明了该函数后,在函数的定义部分使用或不使用DLLAPI修饰都是被允许的。

  1. int MyFunction(int, int) //声明了函数后,在定义部分可以不加修饰符  
  2. {  
  3.               int ret = 0;  
  4.               //...处理  
  5.               return ret;  

也可以只给函数定义,而省略声明部分,这时当然就得加上修饰:

  1. DLLAPI int MyFunction(int, int) //只给出函数定义,必须加上修饰  
  2.  {  
  3.               int ret = 0;  
  4.               //...处理  
  5.               return ret;  
  6. }  
  7.  

我们知道,DLL本身不仅可以导出函数,还可以导出变量和类,但由于P/Invoke只能导入DLL中函数的定义,因此这里只关注函数的导出。

3、  使用DllImport导入函数定义。在C#项目 “DeviceApplication1”添加一个包装类,使用DllImport导入“CppProject”项目的导出函数。

  1. internal class Wrapper  
  2.     {  
  3.         [DllImport("CppProject.dll")]  
  4.         internal static extern int MyFunction(int k1, int k2);  
  5.     } 

4、  修改项目配置实现混合编译。前面的过程只是在一个解决方案下建立了C#项目和C++项目,这两个项目物理上没有进行关联,因此我们必须先编译C++项目,生成"CppProject.dll",然后拷贝该文件到设备上,再运行C#项目时才能通过P/Invoke调用该文件中的导出函数。如果对C++项目进行了修改,必须重复以上过程,非常地麻烦。利用vs2005的集成管理特点,对项目配置进行一下修改,我们就可以在两个项目建立关联。

首先修改C++项目的输出路径,在项目属性的[配置属性]-[常规]-[输出目录]项下,将输出目录改为“$(SolutionDir)\ DeviceApplication1”,即输出到C#项目所在目录。然后生成一下C++项目,这时在C#项目所在目录下会生成“CppProject.dll”文件,将该文件添加到C#项目中,并在属性中修改[复制到输出目录]为“如果较新则复制”。最后在解决方案的项目依赖项中,设置项目“DeviceApplication1”依赖于项目“CppProject”。

通过这样的配置,在启动项目的调试(F5)时,会先生成C++项目,即输出“CppProject.dll”文件到C#项目所在目录,然后再生成C#项目。在生成C#项目的过程中,会检查CppProject.dll是否被更新,如果被更新,则部署到设备上。这样修改了C++项目后同样可以执行启动调试来进行整体调试,不需要再手动去单独编译C++项目,以及复制DLL文件了。

5、  C++DLL项目的调试。vs2005提供了多种调试模式,可以使用本机EXE程序来对DLL进行调试,也可以使用托管 EXE 中对DLL进行调试。这里的DLL项目最终是要被托管C#调用的,因此我们使用由托管C#项目创建的托管 EXE来对C++项目DLL进行调试。

首先设置C++DLL项目为启动项目,并将其项目属性的[配置属性]-[调试]-[远程可执行文件]项改为C#项目输出的EXE程序名,如%CSIDL_PROGRAM_FILES%\MixedSolution\DeviceApplication1.exe,注意该EXE文件是在设备上的路径而不是在本机的路径。该EXE程序名是由C#项目的[输出文件夹] + [程序集名称]确定。

按照以上创建智能设备的C++和C#混合项目的方法,我创建了一个混合项目应用,为C#应用程序增加等待光标(等待动画)的功能,以向用户表明程序正在处理,如下图:

设置等待光标可以使用Windows CE的API函数SetCursor(LoadCursor(NULL, IDC_WAIT));但实际上IDC_WAIT是一个宏,在展开后等于(LPWSTR)((DWORD)((WORD)(32514))),因此IDC_WAIT是无法直接在C#下使用的,因而要在C#下直接使用这个API函数是非常困难的任务。而通过一个DLL项目间接的使用这条API则非常方便。DLL项目向外导出函数SetWaitCursor,这个函数不使用任何参数,可以方便被导入到C#中。这个函数的定义如下:

  1. void SetWaitCursor(void)  
  2. {  
  3.        hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));  

相应的C#的导入定义如下:

  1. internal class Wrapper  
  2. {  
  3.         [DllImport("W32DLL.dll")]  
  4.         internal static extern void SetWaitCursor();  

当然,我们还需要一个恢复光标状态的函数,也使用这种方式进行定义。这里给出全部源码,有兴趣的朋友可以下载。代码在vs2005+ppc2003模拟器下调试通过。

【编辑推荐】

  1. C#字符串操作步骤
  2. C#集成开发环境浅析
  3. Visual C# .NET应用程序
  4. C# TimeLabel控件详解
  5. C#复合控件开发技术
责任编辑:彭凡 来源: 博客园
相关推荐

2009-12-04 14:40:43

Visual Stud

2009-12-16 15:53:34

Visual Stud

2009-12-03 10:04:50

Visual Stud

2010-09-28 08:52:00

C#Visual Stud

2009-12-03 10:38:29

Visual Stud

2011-06-09 15:47:01

Qt Visual Stu

2009-12-03 15:58:33

Visual Stud

2009-09-02 16:21:17

Visual BasiC#语言

2009-08-20 11:03:34

Visual C#使用

2010-04-07 13:13:19

Visual Stud

2009-12-04 10:35:56

Visual Stud

2009-11-24 15:44:26

Visual Stud

2023-10-12 08:41:36

C# 开发工具

2009-12-04 11:17:00

Visual Stud

2009-12-11 09:42:00

Visual Stud

2009-12-09 14:29:11

Visual Stud

2009-11-05 15:43:02

Visual Stud

2009-12-09 16:12:49

Visual Stud

2009-12-04 16:57:52

Visual Stud

2009-08-07 10:53:59

Visual C#Excel
点赞
收藏

51CTO技术栈公众号