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,一经查实,立即删除!

相关文章

Unity中使用RequireComponent,没有添加上组件

using UnityEngine; using System.Collections;[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] public class starTest : MonoBehaviour {private Mesh mesh;void Start(){}void Update(){} }代码是这么写的但是编译完后发现没增加组件&#xff0c; 为啥呢………

html写出日出,描写日出优美句子

太阳升起来了&#xff0c;伴着牧歌跳出了地平线&#xff0c;那万道霞光透过云隙照在一望无垠的大草原上&#xff0c;为这片宽广的原野铺上了一层金辉。描写日出的优美句子应该怎么写?描写日出的优美句子1、光芒四射&#xff0c;把万物都唤醒了&#xff1a;小草睁开了它那朦胧的…

Android之封装支付宝支付

在做Android支付的时候肯定会用到支付宝支付&#xff0c; 根据官方给出的demo做起来非常费劲&#xff0c;所以我们需要一次简单的封装。 封装的代码也很简单&#xff0c;就是将官网给的demo提取出一个类来方便使用。 /*** 支付宝支付* * author lenovo*/ public class Alipay {…

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

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

值得永久收藏的 C# 设计模式套路(三)

设计模式套路&#xff0c;完结篇。今天写写设计模式套路中的最后一部分&#xff1a;行为设计模式。这是这个系列的最后一篇。前两篇在&#xff1a;值得永久收藏的 C# 设计模式套路(一)值得永久收藏的 C# 设计模式套路(二)如果你没有看过前两篇&#xff0c;建议先去看看前两篇&a…

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

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

js 中声明变量 “提前”

1.变量定义提升:声明语句&#xff1a;(1)var声明语句&#xff1a;变量声明语句会被“提前”至脚本或者函数的顶部&#xff0c;但是初始化的操作则还在原来var语句的位置执行。例如&#xff0c;下面的例子&#xff0c;所示&#xff1a;function fun(){alert(x);var x666;alert(x…

运维自动化之使用PHP+MYSQL+SHELL打造私有监控系统(二)

现在开始介绍phpmysqlshell监控系统 1、目的此监控系统主要是通过phpmysqlshell的方式&#xff0c;通过shell脚本对各个机器的其各个服务进行监控&#xff0c;达到及时的了解其各个应用服务的状态&#xff08;如果宕掉与启动&#xff09;&#xff0c;在检测应用服务宕掉时&…

Android之事件总线EventBus详解

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

湘乡江南计算机学校,湘乡职业中等专业学校2021年招生录取分数线

许多学生对自己的职业生涯并没有什么明确的规划,所以没有什么好结果,纯属正常现象。只要不断学习,才能不断收获。由此,本网老师为大家整理了湘乡职业中等专业学校2021年招生录取分数线的相关内容,后期若有变化,一切以官方发布为准。湘乡职业中等专业学校往年参考分数线年份地区…

实验4

#include<stdio.h> int main(void) {double r,h,v,n;printf("Enter r,h and n ");scanf("%lf%lf%lf",&r,&h,&n);if(r<0||h<0){printf("输入错误&#xff0c;重新输入");}else{vcylinder(r,h,n);printf("v%.3f\n&qu…

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

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…

Android之安全退出应用程序的几种方式

当我们做项目的时候,当用户在几秒的时间之内按回车键的时候,需要退出程序,但是退出我们要确保安全退出,防止还有程序还在后台运行,下面介绍几种安全的退出程的几种方式(综合了其它博客的然后加上自己使用的看到的总结) number1: 首先获取当前进程的id,然后杀死该进程。…

西电计算机应用基础 一,15秋西电《计算机应用基础(一)》在线作业答案解析.doc...

西电《计算机应用基础(一)》在线作业一、单选题(共 25 道试题&#xff0c;共 100 分。)1. 下拉式菜单命令项右侧的三角形标记说明&#xff1a;. 该命令项当前正在起作用。. 选择该命令将弹出一个对话框。. 该命令项是级联式命令。. 该命令项无快捷键组合。正确答案&#xff1a;…

SBuild 0.1.4 发布,基于 Scala 的构建系统

SBuild 0.1.4 改进了 Eclipse 插件的稳定性&#xff1b;ZipSchemeHandler的 TargetFile 参数相对于项目目录&#xff1b;一些 Ant 的封装提供更多支持的参数。 SBuild 是基于 Scala 的构建系统&#xff0c;主要特点&#xff1a; 平台无关支持多项目自动检测所需的动作以及新版本…

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

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

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

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