C# 调用 C++ dll的两种方式
目录:
1.非托管方式
2.托管方式
3.介绍 extern "C"
4.介绍 DllImport
1.非托管方式
第一种,非托管方式:调用类和方法https://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
非托管方式,只能调用函数,并且函数在extern "C"的体里面
有一下几种方式,把函数都写了,把接口写了。
//创建对象的方法
extern "C" EXAMPLEUNMANAGEDDLL_API CUnmanagedTestClass* CreateTestClass()
{
return new CUnmanagedTestClass();
}
//释放对象
extern "C" EXAMPLEUNMANAGEDDLL_API void DisposeTestClass(CUnmanagedTestClass* pObject)
{
if(pObject != NULL)
{
delete pObject;
pObject = NULL;
}
}
//调用函数
extern "C" EXAMPLEUNMANAGEDDLL_API void CallPassInt(CUnmanagedTestClass* pObject, int nValue)
{
if(pObject != NULL)
{
pObject->PassInt(nValue);
}
}
//调用函数
extern "C" EXAMPLEUNMANAGEDDLL_API void CallPassString(CUnmanagedTestClass* pObject, char* pchValue);
extern "C"{
EXAMPLEUNMANAGEDDLL_API char* CallReturnString(CUnmanagedTestClass* pObject)
}
C++的调用
把生成的TestClassDLL.dll放到 bin/Debug/下,然后在C#中调用
public class CSUnmanagedTestClass : IDisposable
{
#region PInvokes
[DllImport("TestClassDLL.dll")]
static private extern IntPtr CreateTestClass(); [DllImport("TestClassDLL.dll")]
static private extern void DisposeTestClass(IntPtr pTestClassObject); [DllImport("TestClassDLL.dll")]
static private extern void CallPassInt(IntPtr pTestClassObject, int nValue);
.
.
.
#endregion PInvokes #region Members
private IntPtr m_pNativeObject;
// Variable to hold the C++ class's this pointer
#endregion Members public CSUnmanagedTestClass()
{
// We have to Create an instance of this class through an exported
// function
this.m_pNativeObject = CreateTestClass();
} public void Dispose()
{
Dispose(true);
} protected virtual void Dispose(bool bDisposing)
{
if(this.m_pNativeObject != IntPtr.Zero)
{
// Call the DLL Export to dispose this class
DisposeTestClass(this.m_pNativeObject);
this.m_pNativeObject = IntPtr.Zero;
} if(bDisposing)
{
// No need to call the finalizer since we've now cleaned
// up the unmanaged memory
GC.SuppressFinalize(this);
}
} // This finalizer is called when Garbage collection occurs, but only if
// the IDisposable.Dispose method wasn't already called.
~CSUnmanagedTestClass()
{
Dispose(false);
} #region Wrapper methods
public void PassInt(int nValue)
{
CallPassInt(this.m_pNativeObject, nValue);
}
.
.
.
#endregion Wrapper methods
}
2.托管方式
我手上有一个C++写的类(NativeClass),想在C#下调用这个类,可是C#是没有简单的像Dllimport这样的方法获取非托管C++ dll里的类。我的解决方法是,生成一个托管C++的dll,然后在C#下引用这个dll。因为托管代码与非托管代码是不能在一个文件里混编的,所以我必须将非托管C++写的NativeClass用托管C++的手段封装一下,然后生成一个dll,以供C#调用。
https://www.cnblogs.com/stemon/p/4246165.html
3.介绍 extern "C"
:https://www.cnblogs.com/xiangtingshen/p/10980055.html
extern "C"包含双重含义,
- 被extern "C"修饰的变量和函数是按照C语言方式进行编译和链接的:这点很重要!!!!
extern "C"的使用要点总结
1,可以是如下的单一语句:
extern "C" double sqrt(double);
2,可以是复合语句, 相当于复合语句中的声明都加了extern "C"
extern "C"
{
double sqrt(double);
int min(int, int);
}3,可以包含头文件,相当于头文件中的声明都加了extern "C"
extern "C"
{
#include <cmath>
}
4.介绍 DllImport
https://www.cnblogs.com/fer-team/archive/2017/12/13/8033413.html
要使用DllImport需要引用命名空间: System.Runtime.InteropServices;
DllImport 属性定义
如下:
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName){...} //定位参数为dllName
public CallingConvention CallingConvention; //入口点调用约定
public CharSet CharSet; //入口点采用的字符接
public string EntryPoint; //入口点名称
public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false
public bool PreserveSig; //方法的签名是被保留还是被转换
public bool SetLastError; //FindLastError方法的返回值保存在这里
public string Value {get {...}}
}
}
说明:
1、DllImport只能放置在方法声明上。
2、DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。
3、DllImport具有五个命名参数:
a、CallingConvention 参数指示入口点的调用约定。如果未指定CallingConvention,则使用默认值CallingConvention.Winapi。
b、CharSet参数指定用在入口点的字符集。如果未指定CharSet,则使用默认值CharSet.Auto。
c、EntryPoint参数给出dll中入口点的名称。如果未指定EntryPoint,则使用方法本身的名称。
d、ExactSpelling参数指示EntryPoint是否必须与指示的入口点的拼写完全匹配。如果未指定ExactSpelling,则使用默认值false。
e、PreserveSig参数指示方法的签名被保留还是被转换。当签名被转换时,它被转换为一个具有HRESULT返回值和该返回值的一个名为retval的附加输出参数的签名。如果未指定PreserveSig,则使用默认值true。
f、SetLastError参数指示方法是否保留Win32“上一错误”。如果未指定SetLastError,则使用默认值false。
4、它是一次性属性类。
5、用DllImport属性修饰的方法必须具有extern修饰符。
C# 调用 C++ dll的两种方式的更多相关文章
- C#动态调用WCF接口,两种方式任你选。
写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...
- SoapUI调用webservice实现的两种方式
SoapUI用来做测试,已经是很多人做过的事情了,而且网上教程也很多.不过还是写下来,对比webservice协议与http协议脚本编写的不同. 首先测接口得有一个服务,刚好笔者所在项目做ESB集成. ...
- C++调用C代码的两种方式
由于C++支持函数重载,在编译函数代码的时候会加上参数类型的信息,而C编译只有函数名信息,导致C++直接调用C代码在链接的时候会出现函数未定义的问题.解决这种问题有两种方法.方法一:在写C代码的时候考 ...
- Delphi 调用Dll的两种方式
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- vc导出调用dll的两种方式
一.stdcall 1. #define DLLEXPORT _declspec(dllexport) _stdcall, int DLLEXPORT func(const char *peer,u ...
- javascript消除字符串两边空格的两种方式,面向对象和函数式编程。python oop在调用时候的优点
主要是javascript中消除字符串空格,比较两种方式的不同 //面向对象,消除字符串两边空格 String.prototype.trim = function() { return this.re ...
- 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入
在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...
- WCF 客户端调用服务操作的两种方法
本节的主要内容:1.通过代理类的方式调用服务操作.2.通过通道的方式调用服务操作.3.代码下载 一.通过代理类的方式调用服务操作(两种方式添加代理类) 1.手动编写代理类,如下: 客户端契约: usi ...
- java中调用本地动态链接库(*.DLL)的两种方式详解和not found library、打包成jar,war包dll无法加载等等问题解决办法
我们经常会遇到需要java调用c++的案例,这里就java调用DLL本地动态链接库两种方式,和加载过程中遇到的问题进行详细介绍 1.通过System.loadLibrary("dll名称,不 ...
随机推荐
- <每日 1 OJ> -LeetCode 28. 实现 strStr()
题目: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存 ...
- 【Gamma】设计与计划
目录 需求分析 已实现 功能 用户使用动机分析 当前阶段推广困难 当前阶段任务优先级 主要功能解析 社团活动场地申请 - 实现成本较高,正在调研社长的需求 完善入社流程的信息提示 通知功能 通知管理 ...
- 【转】Android 将自己的应用改为系统应用
所谓系统程序就是system/app目录中的程序,普通应用转换成系统程序后有稳定.减少内存(DATA)空间占用.恢复出厂设置后不会消失.修改系统时间.调用隐藏方法.系统关机重启.静默安装升级卸载应用等 ...
- h5 唤起app或跳转appStore
//唤起app通过唤端媒介(URL Scheme) //微信浏览器自6.3.x版本起禁用了大多数Scheme跳转功能,扫一扫目前可用 // URL 的组成: // [scheme:][// ...
- 二分查找时间复杂度、partition时间复杂度
二分查找时间复杂度 partition时间复杂度 O(n) = O(n) + O(n/2) + O(n/4)+.... 然后用等比求和公式得出是O(2n),即O(n)
- 统计git提交代码量
# a新增行数,d删除行数 git log --author="`git config --get user.name`" --pretty="%H" --a ...
- 图像的ROI区域选择与复制
[opencv学习笔记六]图像的ROI区域选择与复制 孜然 7 人赞同了该文章 图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感 ...
- leetcode No.242 有效的字母异位词 valid-anagram (Python3实现)
题目描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram&q ...
- react一些问题
一.死循环 1.问题描述 function handleClick() { this.setState({count: ++this.state.count}); console.log(" ...
- 百度URL参数解析
在用Python爬取百度搜索的内容时,发现百度搜索的url非常的长,往往会跟一大段的参数,但其实很多参数都是没有必要的,如同样是搜索java关键字,可以通过 http://www.baidu.com/ ...