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,公共 ...
随机推荐
- permissions is only granted to system apps 错误
permissions is only granted to system apps androidstudio中: File - Setting - Editor - Inspections, An ...
- linux学习笔记-linux主机上传下载文件至linux虚拟机的方法
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.上传文件 scp -r file 用户名@ip地址:目标目录 2.下载文件 scp -r 用户名@ip地址:文件 目标目录
- 【20190228】JavaScript-数组的操作
1. 创建数组 var array = new Array(); var array = new Array(5); var array = new Array(1,2,3,"a" ...
- 使用python操作XML增删改查
使用python操作XML增删改查 什么是XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输 ...
- Android 解析标准的点击第三方文件管理器中的视频的intent
解析标准的第三方视频intent private List<String> mCurPlayList = new ArrayList<String>(); private in ...
- dotNet core 应用部署至 centos(超详解附截图)
文章来源:公众号-智能化IT系统. 需要安装的插件以及支撑架构 1.dotnetSDK dotnet 相关命令是属于 .NET Core command-line (CLI) 的一部分,Microso ...
- [20190415]关于shared latch(共享栓锁).txt
[20190415]关于shared latch(共享栓锁).txt http://andreynikolaev.wordpress.com/2010/11/17/shared-latch-behav ...
- SQL 使用临时表和临时变量完成update表字段---实际案例
-- 使用临时表 -- 创建临时表 --ALTER TABLE TS_ExpenseApplication_Reim_Detail ADD BgCode NVARCHAR() NULL, BgItem ...
- .net DLL版本管理
每个DLL打上版本号,方便识别维护
- 【任务】Python语言程序设计.MOOC学习
[博客导航] [Python导航] 任务 18年11月29日开始,通过9周时间跨度,投入约50小时时间,在19年1月25日之前,完成中国大学MOOC平台上的<Python语言程序设计>课程 ...