c# 调用c++DLL方法及注意事项
引用命名空间 using System.Runtime.InteropServices
调用方法:
一、静态加载
用DllImprot方式来加载c++DLL。如下格式:
//对应c++方法
//void DogInit(WORD*,HWND) //错误返回值,窗口句柄
[DllImport("DOG.dll", EntryPoint = "DogInit", CallingConvention = CallingConvention.Cdecl)]
public static extern void DogInit(out short x, IntPtr hwnd); //对应c++方法
//void DogReadInfo(WORD*,int,unsigned char*,unsigned short) //错误返回值,读取哪项,返回的内容,初始化长度
[DllImport("DOG.dll", EntryPoint = "DogReadInfo", CallingConvention = CallingConvention.Cdecl)]
public static extern void DogReadInfo(out short x, int y,[MarshalAs(UnmanagedType.LPArray,SizeConst=)]byte[] z,short w); /// <summary>
/// 初始化加密狗
/// </summary>
public static void DogInit()
{
IntPtr zero = IntPtr.Zero;
short x = -;
DogInit(out x,zero);
//此时x保存了返回的错误码,如0、1、2
} public static void DogReadInfo()
{
short x;
int y = ;
byte[] z = new byte[];
short w = ;
DogReadInfo(out x,y,z,w);
//此时x保存了返回的错误码
//z保存了返回的读取内容
string content = System.Text.Encoding.Default.GetString(z);
}
注意:
1、如果只有一个DLL可以用这种方式,把DLL放在bin/Debug或bin文件夹下,在控制台窗体应用程序和Web网页应用程序都有效。如果有多个DLL,存在依赖调用,如A、B两个DLL,A会调用B里面的方法,因为[DllImport("A.dll")] 这样写只能调用一个DLL,在控制台窗体应用程序中,会自动加载B,但是在Web网页应用程序不会自动加载B,导致返回错误码找不到文件。要是这样写[DllImport("A.dll")] 、[DllImport("B.dll")] ,还是不会加载B。用下面二中的动态加载,依然只能加载一个DLL。解决方法:把A、B复制到系统文件夹下,32位系统复制到c/windows/system32下,64位系统复制到c/windows/syswow64文件夹下,写的时候只用[DllImport("A.dll")],就会自动加载B。这种方式只适用于你可以控制电脑,如果用的别人的服务器空间,没法复制,有可能的话最好把A、B编译到一个DLL中来调用。
2、数据格式对应问题。
二、动态加载
1、用Assembly方式加载,这种方式只适用于托管代码。c++也可以编译为托管代码。依然只能加载一个DLL。
2、用LoadLibrary和GetProcAddress方式加载,这种方式可以加载非托管代码。依然只能加载一个DLL。
如下格式:
public class DllInvoke
{
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(String path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
private IntPtr hLib; public DllInvoke(String DLLPath)
{
hLib = LoadLibrary(DLLPath);
}
~DllInvoke()
{
FreeLibrary(hLib);
}
//将要执行的函数转换为委托
public Delegate Invoke(String APIName,Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api,t);
}
}
//使用时候
public class Class1
{
//定义委托变量
public delegate int C(); public ActionResult Index()
{
//在方法里初始化类
DllInvoke dllInvoke = new DllInvoke("DLL绝对路径"); //也可以把Dll保存在bin下,用相对路径转换为绝对路径
//调用类里面方法
C c = (C) dllInvoke.Invoke("DLL里面方法名如DogInit", typeof (C));
//得到返回值
int result = c.Invoke();
}
}
三、其他方式
在搜索过程中有些关键字也有启示,但没有往下找。如更改Dll搜索目录,加入bin目录到DLL搜索顺序,DllImport加载依赖项Dll。
四、其他文章,看看
http://www.cnblogs.com/szytwo/archive/2011/12/11/2283780.html
http://www.cnblogs.com/kvspas/archive/2008/12/15/1355033.html
如有地方不正确,欢迎提出。
c# 调用c++DLL方法及注意事项的更多相关文章
- C# 调用 C++ DLL方法
在C# 中,可以通过 DllImport 调用C++ 的非托管DLL程序. VS2010中C#调用C++的DLL示例: 一.新建C++ DLL程序 1.新建 C++ Win32项目,类型为DLL. 生 ...
- unity调用c++ dll方法介绍
摘要 unity用的很普遍,现在很多代码还是用c++写的,需要用unity去调用c++的代码.这里介绍了一种unity调用c++ dll的方法,希望有所帮助. 我采用的软件是Visual Studio ...
- ocx控件 编译成C#调用的dll 方法 转
打开VS命令提示行 1.注册ActiveX控件(带上 VCbox.ocx的路径) regsvr32 VCbox.ocx 2.编译OCX文件 aximp VCbox.ocx 生成两个dll文件,项 ...
- 2015.5.9 C#编写DLL及C#调用C#DLL
过程比C#调用VC++dll简单. 一.创建DLL 新建工程,类型选择类库,生成的结果就是dll 注意:在项目属性-应用程序中,注意三个地方,程序集名称和默认命名空间可以调整,但要一致,别的程序调用此 ...
- java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列
1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...
- 在C#调用C++的DLL方法(二)生成托管的DLL
写操作之前,还是扼要的说一下托管与非托管C++的区别好了,其实我也并没有深入了解过托管C++的特点所在,其最大的特征就是可以由系统来调试回收相关的代码资源,跟C#的特性一样,只是编程风格跟C++类似而 ...
- C# 通过反射类动态调用DLL方法
网上看了很多关于反射的思路和方法,发现这个还算不错 //使用反射方: using System; using System.Collections.Generic; using System.Linq ...
- Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()
Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...
- go 调用windows dll 的三种方法
参考:https://blog.csdn.net/qq_39584315/article/details/81287669 大部分代码参考:https://studygolang.com/articl ...
随机推荐
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- eclipse js 报错解决办法
最近项目中的js一直红叉叉,本人本来就是那种看见回收站有东西想清理的那种强迫症患者, 所以对于这种红叉叉更是心烦.这个我已经忍了好久了.今天 见这哥们犀利的解决了这个eclipes的bug.很是激动, ...
- HTTP 2.0与HTTP 1.1区别
1.什么是HTTP 2.0 HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),是HTTP协议的的第二个主要版本,使用于万维网.HTTP/2是HTTP协议自1999年HTTP 1.1发布 ...
- 天津政府应急系统之GIS一张图(arcgis api for flex)讲解(一)GIS一张图的系统开发环境以及flexviewer框架
系统的GIS功能实现是基于arcgis api for flex,首先附上系统的主界面图,接下来的是对主界面的模块功能详细讲解: 一.GIS环境软件安装 (1)arcgis desktop的安装,要是 ...
- sharepoint2013用场管理员进行文档库的爬网提示"没有权限,拒绝"的解决方法
爬网提示被拒绝,场管理员明明可以打开那个站点的,我初步怀疑是:环回请求(LoopbackRequest)导致的 解决方法就是修改环回问题.修改注册表 具体操作方法: http://www.c-shar ...
- (五)Maven目录结构及常用命令说明
前面提到的部分知识有涉及到Maven目录结构与Maven常用的一些命令,在这里专门给大家做个简单的介绍. 1.Maven目录结构说明 Maven总体目录结构如下图: bin目录:该目录包含了mvn运行 ...
- ORA-02266: unique/primary keys in table referenced by enabled foreign keys
在数据库里面使用TRUNCATE命令截断一个表的数据时,遇到如下错误 SQL >TRUNCATE TABLE ESCMOWNER.SUBX_ITEM ORA-02266: unique/prim ...
- SQL SERVER 2014 Agent服务异常停止案例
生产环境一数据库服务器(SQL Server 2014)的Agent服务突然停掉了,检查了错误日志,发现在"SQL Server Agent"里面没有"SQLServer ...
- Sqoop 结合多种系统的具体应用
Sqoop与HDFS结合 下面我们结合 HDFS,介绍 Sqoop 从关系型数据库的导入和导出. Sqoop import 它的功能是将数据从关系型数据库导入 HDFS 中,其流程图如下所示. 我们来 ...
- hive load数据为null
建表语句: CREATE EXTERNAL TABLE IF NOT EXISTS student2 > (sno INT,sname STRING,age INT,sex STRING) &g ...