在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译。这样一来,就涉及C#托管代码与C++非托管代码互相调用,于是调查了一些资料,顺便与大家分享一下:

一. C# 中静态调用C++动态链接

1. 建立VC工程CppDemo,建立的时候选择Win32 Console(dll),选择Dll。

2. 在DllDemo.cpp文件中添加这些代码。

extern "C" __declspec(dllexport) int Add(int a,int b)
{
    
     return a+b;
}

3. 编译工程。

4. 建立新的C#工程,选择Console应用程序,建立测试程序InteropDemo
    5. 在Program.cs中添加引用:using System.Runtime.InteropServices;

6. 在pulic class Program添加如下代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace InteropDemo
{
    class Program
    {
        [DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        public static extern int Add(int a, int b); //DllImport请参照MSDN         static void Main(string[] args)
        {
            Console.WriteLine(Add(1, 2));
            Console.Read();
        }
    }
}

好了,现在您可以测试Add程序了,是不是可以在C# 中调用C++动态链接了,当然这是静态调用,需要将CppDemo编译生成的Dll放在DllDemo程序的Bin目录下

二. C# 中动态调用C++动态链接

在第一节中,讲了静态调用C++动态链接,由于Dll路径的限制,使用的不是很方便,C#中我们经常通过配置动态的调用托管Dll,例如常用的一些设计模式:Abstract Factory, Provider, Strategy模式等等,那么是不是也可以这样动态调用C++动态链接呢?只要您还记得在C++中,通过LoadLibrary, GetProcess, FreeLibrary这几个函数是可以动态调用动态链接的(它们包含在kernel32.dll中),那么问题迎刃而解了,下面我们一步一步实验

1.  将kernel32中的几个方法封装成本地调用类NativeMethod

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace InteropDemo
{
    public static class NativeMethod
    {
        [DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
        public static extern int LoadLibrary(
            [MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);         [DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
        public static extern IntPtr GetProcAddress(int hModule,
            [MarshalAs(UnmanagedType.LPStr)] string lpProcName);         [DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
        public static extern bool FreeLibrary(int hModule);
    }
}

2. 使用NativeMethod类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。原因很简单,C#中已经不能使用指针了,如下          
            int hModule = NativeMethod.LoadLibrary(@"c:"CppDemo.dll");

IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

详细请参见代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace InteropDemo
{
    class Program
    {
        //[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
        //public static extern int Add(int a, int b); //DllImport请参照MSDN         static void Main(string[] args)
        {
            //1. 动态加载C++ Dll
            int hModule = NativeMethod.LoadLibrary(@"c:\CppDemo.dll");
            if (hModule == 0) return;             //2. 读取函数指针
            IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");             //3. 将函数指针封装成委托
            Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));             //4. 测试
            Console.WriteLine(addFunction(1, 2));
            Console.Read();
        }         /// <summary>
        /// 函数指针
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        delegate int Add(int a, int b);     }
}

通过如上两个例子,我们可以在C#中动态或者静态的调用C++写的代码了.

转自:http://www.cnblogs.com/Jianchidaodi/archive/2009/03/09/1407270.html

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

C# 中静态调用C++dll 和C# 中动态调用C++dll的更多相关文章

  1. 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包

    前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”) ...

  2. 动态链接库(dll)文件的动态调用(使用动态链接库,解析Wis文件--测井数据文件的一种)

    在画出井眼轨迹后,老师又给了三口井的数据,不过这次给的数据是WIS格式的,可以使用一个动态链接库进行解析,解析结束后会生成一个固定格式的txt文件,然后再读取txt文件,画井眼轨迹. 学长给了一个可以 ...

  3. 在Delphi中静态调用DLL

    在Delphi中静态调用DLL top 调用一个DLL比写一个DLL要容易一些.首先给大家介绍的是静态调用方法,稍后将介绍动态调用方法,并就两种方法做一个比较.同样的,我们先举一个静态调用的例子. u ...

  4. [转]Delphi DLL的创建、静态 以及动态调用

    第一章  DLL简单介绍 由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结. 首先装简单介绍下DLL: 1,减小可执行文件的大小 DLL技术的产生有很大一部分原因是为了减小可执行 ...

  5. Delphi 类库(DLL)动态调用与静态调用示例讲解

    在Delphi或者其它程序中我们经常需要调用别人写好的DLL类库,下面直接上示例代码演示如何进行动态和静态的调用方法: { ************************************** ...

  6. Delphi Dll 动态调用例子(3)-仔细看一下

    http://blog.163.com/bxf_0011/blog/static/35420330200952075114318/ Delphi 动态链接库的动态和静态调用 为了让人能快速的理解 静态 ...

  7. C#动态调用C++编写的DLL函数

    C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...

  8. java中静态代码执行顺序

    1.Java中静态变量只能在类主体中定义,不能在方法中定义. 静态变量属于类所有而不属于方法. 2. 静态块:用static申明,JVM加载类时执行,仅执行一次 构造块:类中直接用{}定义,每一次创建 ...

  9. 10、一个action中处理多个方法的调用第一种方法动态调用

    我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...

  10. 动态调用WebService(C#) (非常实用)

    通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...

随机推荐

  1. CentOS安装Hadoop

    Hadoop的核心由3个部分组成: HDFS: Hadoop Distributed File System,分布式文件系统,hdfs还可以再细分为NameNode.SecondaryNameNode ...

  2. Alpha冲刺(11/10)——2019.5.3

    作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...

  3. python 关于celery的定时任务队列的基本使用(celery+redis)【采用配置文件设置】

    工程结构沿用https://www.cnblogs.com/apple2016/p/11422388.html,只需修改celeryconfig.py文件即可: 1.更新celeyconfig.py文 ...

  4. Git/SVN提交代码规范

    feat - 新功能 feature fix - 修复 bug docs - 文档注释 style - 代码格式(不影响代码运行的变动) refactor - 重构.优化(既不增加新功能,也不是修复b ...

  5. redux本来是同步的为什么它能执行异步代码(chunk)实现原理是什么 中间件的实现原理是什么

    我们用redux执行同步的时候,都是先发起一个dispatch(actionCreator()) 1.先在actionCreator()中生成一个action对象. 2.由dispatch方法将act ...

  6. Mysql 8.0版本开始,不允许创建 MyISAM 分区表

    从MySQL 8.0版本开始,就不允许创建 MyISAM 分区表了,只允许创建已经实现了本地分区策略的引擎. 到目前为止,只有InnoDB和NDB这两个引擎支持本地分区策略. [1]实际测试 (1)数 ...

  7. 金九银十跳槽高峰,面试必备之 Redis + MongoDB 常问80道面试题

    前言 有着“金九银十”之称的招聘旺季已经开启,跳槽高峰期也如约而至. 本文为主要是 Redis + MongoDB 知识点的攻略,希望能帮助到大家. 内容较多,大家准备好耐心和瓜子矿泉水. Redis ...

  8. Akka-CQRS(12)- akka-http for http-web-service: Routing-服务项目接口

    上篇提到,按当前对web-service功能需要,我们需要完成数据转换marshalling,服务接口routing这两部分的调研和示范.上篇已经完成了对序列化marshalling的讨论,这篇就介绍 ...

  9. 移动端可视化框架antv f2出现两个legend选项

    前天遇到个坑,把我给坑死了 ,在帮朋友做一个微信公众号的项目,使用的vue全家桶,有个模块需要用到数据可视化展现,之前做项目的时候用过antv,比较熟悉,因为是移动端的项目,所以用的是antv f2这 ...

  10. - Java中boolean类型占用多少个字节 MD

    目录 目录 Java中boolean类型占用多少个字节 1个bit(1位) 1个Byte(1字节,8位) 4个Byte(4字节,32位) 分析 官方文档中的描述 Markdown版本笔记 我的GitH ...