• .net项目引用C++ 动态链接库.dll


      项目开发时可能需要调用其动态链接库,如C++动态链接库,实现相应功能,那么在C#里怎么调用C++库里的方法呢,如下提供两种方式。

    方式一:建立一个C++项目,选择dll动态链接库如下。 

     1 //stdafx.h 文件内容 
     2 //#ifdef  func_api 
     3 //#else
     4 //#define func_api extern "C" __declspec(dllimport)  
     5 //#endif
     6 
     7 #define func_api extern "C" __declspec(dllexport)
     8 func_api double Add1(double x, double y);
     9 
    10 func_api double Sub1(double x, double y);
    11 
    12 func_api double Multiply1(double x, double y);
    13 
    14 func_api double Divide1(double x, double y);

    如上定义个宏func_api,用于导出C++项目中函数所定义的标示符__declspec(dllexport),其中extern "C"是作用就是在编译时用c的方式编译,也就是不让函数名字变化,因为用C++编译器编译后的函数名称会变化,如add1编译后可能是@ILT+575(_Add1)或什么的不同编译器不同,为了防止客户端可以调到这个函数所以用 extern "C" 这样编译后的函数名称就不变了。

     1 // ConsoleApplication1.cpp 文件内容: 定义 DLL 应用程序的导出函数。
     2 //#define func_api extern "C" __declspec(dllexport)
     3 #include "stdafx.h"
     4  double Add1(double x, double y)
     5 {
     6     return x + y;
     7 }
     8  double Sub1(double x, double y)
     9 {
    10     return x - y;
    11 }
    12  double Multiply1(double x, double y)
    13 {
    14     return x * y;
    15 }
    16   double Divide1(double x, double y)
    17 {
    18     return x / y;
    19 }

     方式二:建立一个C++空项目,选择dll动态链接库如下。

     添加头文件MathTest.h 代码如下。

     1 #pragma once
     2 namespace MathFuncs
     3 {
     4     class MyMathFuncs
     5     {
     6     public:
     7         // Returns a + b
     8         static __declspec(dllexport) double Add(double a, double b);
     9 
    10         // Returns a - b
    11         static __declspec(dllexport) double Subtract(double a, double b);
    12 
    13         // Returns a * b
    14         static __declspec(dllexport) double Multiply(double a, double b);
    15 
    16         // Returns a / b
    17         static __declspec(dllexport) double Divide(double a, double b);
    18 
    19     };
    20 }

     添加C++文件MathTest.cpp

     1 // MathTest.cpp
     2 // compile with: /EHsc /LD
     3 
     4 #include "MathTest.h"
     5 #include <stdexcept> 
     6 using namespace std;
     7 namespace MathFuncs
     8 {
     9     double MyMathFuncs::Add(double a, double b)
    10     {
    11         return a + b;
    12     }
    13 
    14     double MyMathFuncs::Subtract(double a, double b)
    15     {
    16         return a - b;
    17     }
    18 
    19     double MyMathFuncs::Multiply(double a, double b)
    20     {
    21         return a * b;
    22     }
    23 
    24     double MyMathFuncs::Divide(double a, double b)
    25     {
    26         if (b == 0)
    27         {
    28             throw new invalid_argument("b cannot be zero!");
    29         }
    30 
    31         return a / b;
    32     }
    33 }

    添加模块定义文件,这个文件定义导出函数的名称,这样导出的函数名字就不会变了。

    LIBRARY ConsoleApplication2
    EXPORTS  
    Add @1
    Subtract @2
    Multiply @3
    Divide   @4

     测试姓名,建立一个C# 控制台项目。

     代码如下。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Runtime.InteropServices;
     7 namespace TestDll
     8 {
     9     class Program
    10     {
    11         [DllImport(@"F:	est_projectC++ConsoleApplication1DebugConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)]
    12         public static extern double Add1(double x, double y);
    13         [DllImport(@"F:	est_projectC++ConsoleApplication1DebugConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl)]
    14         public static extern double Multiply1(double x, double y);
    15 
    16         [DllImport(@"F:	est_projectC++ConsoleApplication1DebugConsoleApplication2.dll", CallingConvention = CallingConvention.Cdecl)]
    17         public static extern double Add(double x, double y);
    18         [DllImport(@"F:	est_projectC++ConsoleApplication1DebugConsoleApplication2.dll", CallingConvention = CallingConvention.Cdecl)]
    19         public static extern double Multiply(double x, double y);
    20         static void Main(string[] args)
    21         {
    22 
    23             double result = Add1(10, 20);
    24             Console.WriteLine("The result of add1 is {0}", result);
    25             double result1 = Multiply1(10, 20);
    26             Console.WriteLine("The result of Sub1 is {0}", result1);
    27             Console.WriteLine("========================================");
    28 
    29 
    30             double result11 = Add(10, 20);
    31             Console.WriteLine("The result of add is {0}", result11);
    32             double result111 = Multiply(10, 20);
    33             Console.WriteLine("The result of Subtract is {0}", result111);
    34             Console.Read();
    35 
    36         }
    37     }
    38 }

     

    如果想看C++动态链接库是否有函数导出可以用这个工具dumpbin.exe ,默认路径C:Program Files (x86)Microsoft Visual Studio 14.0VCin,很据你vs安装路径下找到它,如下。

    注:1.extern "C"  不能导出成员函数。

         2.使用标准调用方式_stdcall,函数名称还是会发生改变。

     附件链接: https://pan.baidu.com/s/1o8RfgIu 密码: etha

  • 相关阅读:
    Spring之调度器(Scheduler)
    Spring之拦截器(Interceptor)
    ThreadLocal相关
    hibernate操作数据库
    文件操作的工具类
    日期操作工具类
    有关mysql的utf8和utf8mb4,以及Illegal mix of collations for operation 'like'
    [原]nginx 一下快一下慢的问题
    再谈微信公众号网页授权的40163错误
    用DBCC CHECK修复SQL2000的数据库一致性问题
  • 原文地址:https://www.cnblogs.com/Dream618/p/5774318.html
Copyright © 2020-2023  润新知