C# 中静态调用C++dll 和C# 中动态调用C++dll

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

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

 

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

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

Code
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添加如下代码: 

 

Code
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(
12));
            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

Code
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");

详细请参见代码

Code
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 == 0return;

            
//2. 读取函数指针
            IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

            
//3. 将函数指针封装成委托
            Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));

            
//4. 测试
            Console.WriteLine(addFunction(12));
            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

 

转载于:https://www.cnblogs.com/newstart/archive/2012/10/24/2736780.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294865.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有生之年必看!千古第一奇书《山海经》到底是怎样的一本书?

▲点击查看提到《山海经》&#xff0c;大家应该都耳熟能详。作为一部富有神话色彩的千古奇书&#xff0c;它记载了各种脍炙人口的神话传说&#xff0c;像女娲造人、夸父逐日、羿射九日、精卫填海、大禹治水……都是从这里诞生的。除了神话传说&#xff0c;它内容之博大&#xf…

sv队列和动态数组的区别_Go 刷 LeetCode 系列:经典(7) 设计双端队列

设计实现双端队列。你的实现需要支持以下操作&#xff1a;MyCircularDeque(k)&#xff1a;构造函数,双端队列的大小为k。insertFront()&#xff1a;将一个元素添加到双端队列头部。如果操作成功返回 true。insertLast()&#xff1a;将一个元素添加到双端队列尾部。如果操作成功…

Android之事件总线EventBus详解

顾名思义&#xff0c;AndroidEventBus是一个Android平台的事件总线框架&#xff0c;它简化了Activity、Fragment、Service等组件之间的交互&#xff0c;很大程度上降低了它们之间的耦合&#xff0c;使我们的代码更加简洁&#xff0c;耦合性更低&#xff0c;提升了我们的代码质量…

当女朋友问你会不会出轨的时候,该怎么回答?

1 大象为什么会害怕体型小的动物&#xff1f;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 学会说话很重要&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 原来&#xff0c;他们的老爸是一串香肠&#xff1f;&#xff08;素材来源网络&#xff0c;侵…

WPF开源项目:WPF-ControlBase

仓库截图仓库README很素&#xff0c;但看作者README贴的几篇博文介绍&#xff0c;你会喜欢上它的&#xff0c;废话不多说&#xff0c;上介绍目录&#xff1a;动画封装https://blog.csdn.net/u010975589/article/details/95974854属性表单https://blog.csdn.net/u010975589/arti…

Win10系统修改MAC地址

本地管理地址&#xff0c;输入想修改的MAC地址后&#xff0c;点确定即完成修改。在CMD窗口中&#xff0c;使用ipconfig 命令可以查看新的MAC地址。 再次钩选不存在&#xff0c;则还原为原来的MAC地址。

ftp上传图片出现550_FtpClient 实现文件上传

FtpUtils 工具类封装 public static boolean uploadFile( String hostname, int port, String username, String password, String pathname, String remote,InputStream local) { boolean flagfalse; try{ //创建 FtpClient 对象 FTPClient clientnew FTPClient…

ZOJ 3228(AC自动机+修改的匹配)

题目大意&#xff1a;给出一个字符串和若干个单词&#xff0c;问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现&#xff0c;1为不可重叠出现。 分析&#xff1a;可重叠出现的单词可以直接用ac自动机就解决。至于不可重叠的单词&#xff0c;可以用一个数…

一篇论文未发博士毕业,中科院最年轻院士入职浙大

全世界只有3.14 % 的人关注了爆炸吧知识本文由科研大匠&#xff08;Id:keyandajiang&#xff09;综合整理自科技日报、网络、科研大匠等11月30日&#xff0c;浙江大学官微转载《浙江日报》头版文章消息提到&#xff0c;“目前中国最年轻的中科院院士孙斌勇已入职数学高等研究院…

4.7、Bootstrap V4自学之路------组件---广告屏

为什么80%的码农都做不了架构师&#xff1f;>>> 示例 单独的一个空的标签 <div class"jumbotron"><!-- 背景色是灰色的--> <div> PS&#xff1a;可以看出来&#xff0c;其中上下边距还是挺高的。 <div class"jumbotron"&…

计算机和hdmi无法正常显示,HDMI都不灵 为什么电脑连电视效果差?

1电脑连接电视用法人群庞大【中关村在线显示器频道原创】目前的桌面级显示器尺寸最大的范围就是30英寸&#xff0c;但是30英寸的显示器产品价格过于昂贵&#xff0c;因此很少有消费者能够选择购买。因此&#xff0c;目前大部分消费者都会购买27英寸的显示器&#xff0c;但是问题…

easyui 修改单元格内容_初学Excel办公软件快速修改文字的方法

今天我们学习Excel办公软件快速修改文字的方法&#xff0c;首先我们看这个表格里面的文字很多都是相差一个字&#xff0c;甚至很多内容相差不大&#xff0c;因此我们在输入文字时就需要改进快速方法了。首先我们根据图片来操作&#xff0c;我们修改红色字体里的数据&#xff0c…

Android display架构分析

这篇文章非常好&#xff0c;必须转载。目录(?)[-] Kernel Space Display架构介绍函数和数据结构介绍函数和数据结构介绍函数和数据结构介绍数据流分析初始化过程分析User Space display接口Kernel display接口典型应用flow分析介绍 Surface manager&#xff08;surface flinge…

从状态转移看:载波侦听多路访问/冲突避免(CSMA/CA)

CSMA/CA是写入IEEE802.11的无线网络MAC层标准协议&#xff0c;相信看到这篇文章的读者都知道它是用来做什么的。但许多短文对这个协议的解释都有所缺乏&#xff0c;因此本文用状态转换图的形式详细说明协议的工作流程。&#xff08;好吧其实是作者看到一个状态图有感而发&#…

年度迷惑新闻:美女其实是个男生?

1 南方人为什么不喜欢冬天&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 老板果然是有两把刷子&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 干大事者必是单身狗&#xff1f;&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 把狗子的铁饭…

The import com.sun.tools cannot be resolved

2019独角兽企业重金招聘Python工程师标准>>> 这是因为在myeclipse中&#xff0c;有自带的jar包&#xff1b;儿导入eclipse中&#xff0c;用的是自己安装的jre&#xff0c;tool.jar包是在JDK中&#xff0c;不是在jre中,所以window-》preferrence-》java-》installed …

Android之发送短信后按钮(60秒)变灰色每隔一秒递减显示

无论是做PC端还是android端,每次注册都有发送短信之后,60秒每隔一秒递减显示,如下图 这个地方需要注意的是按钮变灰色之后不能再点击,然后就是android更新UI,需要用handle,或者其它post方式,关键代码如下 /*** 显示时间在梯减的文本框*/public void showTime() {new T…

AgileConfig-1.5.5 发布 - 支持 JSON 编辑模式

本次更新加入了2个新的编辑模式&#xff1a;JSON 编辑模式、TEXT 编辑模式。特别是 JSON 编辑模式是大家比较期待的一个功能。因为大家都习惯了 appsettings.json 的配置编辑模式&#xff0c;所以天生的喜欢 JSON 视图。有了 JSON 编辑模式后&#xff0c;大家就可以直接把原来的…

桩筏有限元中的弹性板计算_永清县打桩机租赁钢板桩租赁怎么联系?

永清县打桩机租赁钢板桩租赁怎么联系&#xff1f;选择专业(产品)震宇建筑工程有限公司震宇钢板桩工程有限公司是一家专业拉森钢板桩工程施工的公司&#xff0c;注册资金1000万&#xff0c;专注钢板桩工程施工20年年经验&#xff0c;经过多年发展&#xff0c;目前震宇钢板桩在广…

(c语言)二叉树中序线索(数据结构十七)

1.数据类型定义在代码中为了清楚的表示一些错误和函数运行状态&#xff0c;我们预先定义一些变量来表示这些状态。在head.h头文件中有如下定义&#xff1a; //定义数据结构中要用到的一些变量和类型 #ifndef HEAD_H #define HEAD_H#include <stdio.h> #include <mallo…