zoukankan      html  css  js  c++  java
  • .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

  • 相关阅读:
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    springboot 整合flowable 项目源码 mybiats vue.js 前后分离 跨域
    flowable Springboot vue.js 前后分离 跨域 有代码生成器 工作流
    Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    java 企业 网站源码 后台 springmvc SSM 前台 静态化 代码生成器
    java 进销存 商户管理 系统 管理 库存管理 销售报表springmvc SSM项目
    基于FPGA的电子计算器设计(中)
    基于FPGA的电子计算器设计(上)
    FPGA零基础学习:SPI 协议驱动设计
    Signal tap 逻辑分析仪使用教程
  • 原文地址:https://www.cnblogs.com/Dream618/p/5774318.html
Copyright © 2011-2022 走看看