C#调用C++ dll编写的程序


title: 'C#调用C++ dll编写的程序'
date: 2016-04-10 18:37:16
tags: C#
categories: c#


编写c dll

  1. 创建一个win32程序,选择DLL
  2. 新建一个.h 文件比如 CDLL.h
  3. 创建一个.cpp文件 CDLL.cpp
C#调用C++ dll编写的程序_第1张图片
extern  "C" _declspec(dllexport) int Add(int x, int y)
{
    return x + y;
}
extern  "C" _declspec(dllexport) int Sub(int x, int y)
{
    return x - y;
}

  1. 在.h 文件对函数进行申明
  2. 在.cpp文件里对文件定义

extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标>是“extern”的;其次,被它修饰的目标是“C”的。而被extern "C"修饰 >的变量和函数是按照C语言方式编译和连接的。
__declspec(dllexport)的目的是为了将对应的函数放入到DLL动态库中。 extern "C" __declspec(dllexport)加起来的目的是为了使用DllImport调用非托管C++的DLL文件。因为使用DllImport只能调用由C语言函数做成的DLL。

c#调用dll

  1. 将该dll放到c#文件目录下
  2. 开始编写代码
[DllImport("Win32Project1.dll", EntryPoint = "Add", CharSet = CharSet.Auto,CallingConvention = CallingConvention.Cdecl)]
        extern static int Add(int x, int y);

[DllImport("Win32Project1.dll", EntryPoint = "Sub", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        extern static int Sub(int x, int y);
        static void Main(string[] args)
        {
            Console.WriteLine(Add(10, 2).ToString());
            Console.WriteLine(Sub(10, 2).ToString());
            Console.Read();
        }

dllimport 调用该dll, EntryPoint 调用函数的名字,CharSet 字符编码,
CharSet属性是用来确定在托管与非托管调用的过程中用什么字符编码来封送数据,因为我们的.NET平台是采用的Unicode编码,而标准C++是采用的Ansi编码,在我们了解了非托管代码的编码方式之后,我们就很确定用什么编码,那么如果我们不清楚非托管代码是用什么语言编写的或者不清楚它的编码方式时,我们可以使用CharSet枚举中的auto值,让CLR自动为我们处理相关细节;
DllImport特性中的CallingConvention可选属性;
CallingConvention属性也是一个比较重要的属性,在平台调用的过程中起到查找入口点的作用,在托管代码进行非托管代码入口点查找时,会通过CallingConvention中的值进行确认非托管入口点的调用约定,上篇文章中我们提到了调用约定的一些概念,

tips

我在写好代码后报错,在百度一番后知道是x86的dll在64位的程序里调用会出问题,所以我调整了Any cpu 为x86.然后可以正常运行了.

你可能感兴趣的:(C#调用C++ dll编写的程序)