C# 中静态调用C++dll 和C# 中动态调用C++dll
在最近的项目中,牵涉到项目源代码保密问题,由于代码是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的更多相关文章
- 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包
前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”) ...
- 动态链接库(dll)文件的动态调用(使用动态链接库,解析Wis文件--测井数据文件的一种)
在画出井眼轨迹后,老师又给了三口井的数据,不过这次给的数据是WIS格式的,可以使用一个动态链接库进行解析,解析结束后会生成一个固定格式的txt文件,然后再读取txt文件,画井眼轨迹. 学长给了一个可以 ...
- 在Delphi中静态调用DLL
在Delphi中静态调用DLL top 调用一个DLL比写一个DLL要容易一些.首先给大家介绍的是静态调用方法,稍后将介绍动态调用方法,并就两种方法做一个比较.同样的,我们先举一个静态调用的例子. u ...
- [转]Delphi DLL的创建、静态 以及动态调用
第一章 DLL简单介绍 由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结. 首先装简单介绍下DLL: 1,减小可执行文件的大小 DLL技术的产生有很大一部分原因是为了减小可执行 ...
- Delphi 类库(DLL)动态调用与静态调用示例讲解
在Delphi或者其它程序中我们经常需要调用别人写好的DLL类库,下面直接上示例代码演示如何进行动态和静态的调用方法: { ************************************** ...
- Delphi Dll 动态调用例子(3)-仔细看一下
http://blog.163.com/bxf_0011/blog/static/35420330200952075114318/ Delphi 动态链接库的动态和静态调用 为了让人能快速的理解 静态 ...
- C#动态调用C++编写的DLL函数
C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...
- java中静态代码执行顺序
1.Java中静态变量只能在类主体中定义,不能在方法中定义. 静态变量属于类所有而不属于方法. 2. 静态块:用static申明,JVM加载类时执行,仅执行一次 构造块:类中直接用{}定义,每一次创建 ...
- 10、一个action中处理多个方法的调用第一种方法动态调用
我们新建一个用户的action package com.weiyuan.test; import com.opensymphony.xwork2.ActionSupport; /** * * 这里不用 ...
- 动态调用WebService(C#) (非常实用)
通常我们在程序中需要调用WebService时,都是通过“添加Web引用”,让VS.NET环境来为我们生成服务代理,然后调用对应的Web服务.这样是使工作简单了,但是却和提供Web服务的URL.方法名 ...
随机推荐
- CentOS安装Hadoop
Hadoop的核心由3个部分组成: HDFS: Hadoop Distributed File System,分布式文件系统,hdfs还可以再细分为NameNode.SecondaryNameNode ...
- Alpha冲刺(11/10)——2019.5.3
作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...
- python 关于celery的定时任务队列的基本使用(celery+redis)【采用配置文件设置】
工程结构沿用https://www.cnblogs.com/apple2016/p/11422388.html,只需修改celeryconfig.py文件即可: 1.更新celeyconfig.py文 ...
- Git/SVN提交代码规范
feat - 新功能 feature fix - 修复 bug docs - 文档注释 style - 代码格式(不影响代码运行的变动) refactor - 重构.优化(既不增加新功能,也不是修复b ...
- redux本来是同步的为什么它能执行异步代码(chunk)实现原理是什么 中间件的实现原理是什么
我们用redux执行同步的时候,都是先发起一个dispatch(actionCreator()) 1.先在actionCreator()中生成一个action对象. 2.由dispatch方法将act ...
- Mysql 8.0版本开始,不允许创建 MyISAM 分区表
从MySQL 8.0版本开始,就不允许创建 MyISAM 分区表了,只允许创建已经实现了本地分区策略的引擎. 到目前为止,只有InnoDB和NDB这两个引擎支持本地分区策略. [1]实际测试 (1)数 ...
- 金九银十跳槽高峰,面试必备之 Redis + MongoDB 常问80道面试题
前言 有着“金九银十”之称的招聘旺季已经开启,跳槽高峰期也如约而至. 本文为主要是 Redis + MongoDB 知识点的攻略,希望能帮助到大家. 内容较多,大家准备好耐心和瓜子矿泉水. Redis ...
- Akka-CQRS(12)- akka-http for http-web-service: Routing-服务项目接口
上篇提到,按当前对web-service功能需要,我们需要完成数据转换marshalling,服务接口routing这两部分的调研和示范.上篇已经完成了对序列化marshalling的讨论,这篇就介绍 ...
- 移动端可视化框架antv f2出现两个legend选项
前天遇到个坑,把我给坑死了 ,在帮朋友做一个微信公众号的项目,使用的vue全家桶,有个模块需要用到数据可视化展现,之前做项目的时候用过antv,比较熟悉,因为是移动端的项目,所以用的是antv f2这 ...
- - Java中boolean类型占用多少个字节 MD
目录 目录 Java中boolean类型占用多少个字节 1个bit(1位) 1个Byte(1字节,8位) 4个Byte(4字节,32位) 分析 官方文档中的描述 Markdown版本笔记 我的GitH ...