C#直接使用DllImport调用C/C++动态库(dll文件)
1.C/C++动态库的编写
下面是我编写的一个比较简单的C++dll文件用来测试,关于如何编写dll文件,我这里便不再赘述,不懂得自行查询,
(1).h文件
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif//求两个整数的和(普通类型的参数)
extern "C" MYDLL_API int GetSum(int nNum1, int nNum2);
//获取两个整数中的最大值(含有整数类型的指针为参数)
extern "C" MYDLL_API int GetMaxValue(int *pValue1, int* pValue2);
//获取两个整数中的最小值,最小值以传出参数获取
extern "C" MYDLL_API void GetMinValue(int *pValue1, int* pValue2, int *pMinValue);
//带有char[]与char*参数
extern "C" MYDLL_API int GetLength(char szName[], char* szBirth);
(2).cpp文件
//求两个整数的和(普通类型的参数)
extern "C" MYDLL_API int GetSum(int nNum1, int nNum2)
{
return (nNum1 + nNum2);
} //获取整个整数中的最大值
extern "C" MYDLL_API int GetMaxValue(int *pValue1, int* pValue2)
{
return (*pValue1 > *pValue2) ? *pValue1 : *pValue2;
} //获取两个整数中的最小值,最小值以传出参数获取
extern "C" MYDLL_API void GetMinValue(int *pValue1, int* pValue2, int *pMinValue)
{
if (*pValue1 < *pValue2)
{
*pMinValue = *pValue1;
}
else
{
*pMinValue = *pValue2;
}
}
//带有char[]与char*参数
extern "C" MYDLL_API int GetLength(char szName[], char* szBirth)
{
return (strlen(szName) + strlen(szBirth));
}
2.在C#项目中封装上述库文件为C#接口
上述库文件编译成功后,需要把它拷贝到C#项目的运行目录下,然后代码中使用using System.Runtime.InteropService命名空间即可引用
如果不想直接拷贝,可在C#项目中建立一个文件夹,如名称为Dll,将上述库文件拷贝到此文件夹,然后打开C#项目,点击项目->属性->生成事件中添加copy "$(SolutionDir)Dll\*.dll" "$(TargetDir)此批处理语句。程序编译成功后便会自行将此库文件拷贝到运行目录下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; namespace Dll_Test
{
public class MyDllHelper
{
private delegate void CallBackDelegate(int nValue1, int nValue2);
//接口实现
public int GetMySum(int num1, int num2)
{
return (GetSum(num1, num2));
} public int GetMyMaxValue(IntPtr Value1, IntPtr Value2)
{
return GetMaxValue(Value1, Value2);
} public void GetMyMinValue(IntPtr Value1, IntPtr Value2, ref int MinValue)
{
GetMinValue(Value1, Value2, ref MinValue);
} public int GetMyLength(string strName, string strBirth)
{
return GetLength(strName, strBirth);
} [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetSum(int num1, int num2);
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int GetMaxValue(IntPtr Value1, IntPtr pValue2);
[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void GetMinValue(IntPtr Value1, IntPtr Value2, ref int MinValue);
[DllImport("MyDll.dll", CallingConvention =CallingConvention.Cdecl)]
private static extern int GetLength(string strName, string strBirth);
}
}
3.接口实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks; namespace Dll_Test
{
class Program
{
static void Main(string[] args)
{
MyDllHelper myDll = new MyDllHelper();
Console.WriteLine("两个整数和为:{0}", myDll.GetMySum(, )); int nValue1 = ;
int nValue2 = ;
IntPtr ptr1 = Marshal.AllocHGlobal(sizeof(int));
IntPtr ptr2 = Marshal.AllocHGlobal(sizeof(int)); Marshal.WriteInt32(ptr1, nValue1);
Marshal.WriteInt32(ptr2, nValue2);
Console.WriteLine("两个整数中的最大值:{0}", myDll.GetMyMaxValue(ptr1, ptr2)); int nMinValue = ;
myDll.GetMyMinValue(ptr1, ptr2, ref nMinValue);
Console.WriteLine("两个整数中最大值:{0}", nMinValue); Marshal.FreeHGlobal(ptr1);
Marshal.FreeHGlobal(ptr2); string strName = "zhangsan";
string strBirth = "1993-01-01";
int nLength = myDll.GetMyLength(strName, strBirth);
Console.WriteLine("两个字符串的总长度为:{0}", nLength); Console.ReadKey();
}
}
}
C#直接使用DllImport调用C/C++动态库(dll文件)的更多相关文章
- Android NDK开发及调用标准linux动态库.so文件
源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...
- C++调用C#的动态库dll
以往我们经常是需要使用C#来调用C++的dll,这通过PInvoke就能实现.现在在实际的项目过程中,有时会遇到在C++的项目中调用某个C#的dll来完成特定的某个功能,我们都知道,Native C+ ...
- C/C++ 关于生成静态库(lib)/动态库(dll)文件如何使用(基于windows基础篇)
1. 首先,如何制作一个静态库(lib)? 额, 对于静态库,我们知道,里头是不应该有Main函数,它只是一个配合文件.之所以称之为lib静态库,其实就是指,我们需要用到lib里头的函数时,我们才会去 ...
- Java 加载动态库 dll 文件
不知道具体原理,但是,加载 dll 文件时,带路径或者更改 dll 文件的名字,都会报错.虽然库记载成功了,但是处女座认为这不可接受.于是有了这个解决方案. 在根目录为库创建软连接,然后使用 syst ...
- C# 调用其他的动态库开发应注意的问题
1.背景 程序开发语言可以说是五花八门,这就引出了一个新问题 ,不同语言开发的系统进行对接时相关调用的问题. 下面我主要说一下我自己在做接口开发时遇到的问题及解决方法仅供参考,我使用的C#开发进行对接 ...
- 在VS2015中用C++编写可被其它语言调用的动态库DLL
转自:http://blog.csdn.net/songyi160/article/details/50754705 VS2015用C++创建动态库DLL步骤如下: (1)启动VS2015>文件 ...
- 关于C#调用非托管动态库方式的性能疑问
最近的项目中,因为一些原因,需要C#调用非托管(这里为C++)的动态库.网上喜闻乐见的方式是采用静态(DllImport)方式进行调用.偶然在园子里看到可以用动态(LoadLibrary,GetPro ...
- C#调用C/C++动态库 封送结构体,结构体数组
一. 结构体的传递 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int ...
- C++与C#有关对库(动态库dll,静态库.lib)文件的调用
1 动态库的相互调用 1.1 C#调用C++ dll步骤(只能导出方法): 1. c++建立空项目->源文件文件夹中添加cpp文件和函数 2. c++属性设置中,配置类型设置为动态库dll,公共 ...
随机推荐
- Docker 更新镜像
docker镜像如下: 今天在运行的容器内使用 apt-get update 命令进行更新时,发下很多404错误. Err http://archive.ubuntu.com wily-updates ...
- Spring Boot入门-快速搭建web项目
Spring Boot 概述: Spring Boot makes it easy to create stand-alone, production-grade Spring based Appli ...
- Java开发笔记(六十九)泛型类的定义及其运用
前面从泛型方法的用法介绍到了泛型的起源,既然单个方法允许拥有泛化的参数类型,那么一个类也应当支持类级别的泛化类型,例如各种容器类型ArrayList.HashMap等等.一旦某个类的定义代码在类名称后 ...
- Android开发——EditText的属性使用
最近使用的EditText控件,有些属性不太清楚,做一下笔记 判断EditText中内容是否为空 EditText多行显示 android:inputType="textMultiLin ...
- rocketmq 发送时异常:system busy 和 broker busy 解决方案
记一次 rocketmq 使用时的异常. 这里就不说什么rocketmq 源码啥的了,因为没看过.网上一搜这两个异常 大部分都是什么源码解读,也没说出现后的解决办法(蓝瘦香菇). 大量测试发现: 1. ...
- Spring webflux
Spring-webflux Spring 5.0 Spring-webflux 是一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的.非堵塞的.事件驱动的服务. sprin ...
- 在虚拟机中搭建qduoj(二)——安装OJ
在上一章中,我们已经做好了准备工作,现在,正式开始搭建OJ. 可以先看看官方文档: https://github.com/QingdaoU/OnlineJudgeDeploy/tree/2.0 运行p ...
- zabbix server3.4 使用mailx配置邮件报警
软件具体配置如下: 操作系统:Centos7.5 zabbix server版本:zabbix server3.4 zabbix agent版本:zabbix agent3.0 现在开始配置zabbi ...
- 电脑一键U盘启动快捷键
下面是我特意列出的品牌电脑.笔记本电脑.组装电脑一键U盘启动快捷键对应列表,仅供大家查阅参考! [品牌-笔记本电脑] 笔记本品牌 启动按键 联想笔记本 F12 宏基笔记本 F12 华硕笔记本 ...
- Linux 文件权限管理
1.文件权限的概述 在Linux系统下,使用权限来保护资源的安全将是一种不错的选择.系统中每个文件的权限都有可读(r).可写(w)和可执行(x)这三种权限,它们分别对应权限数值4.2 和1.系统为每个 ...