引用命名空间 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方法及注意事项的更多相关文章

  1. C# 调用 C++ DLL方法

    在C# 中,可以通过 DllImport 调用C++ 的非托管DLL程序. VS2010中C#调用C++的DLL示例: 一.新建C++ DLL程序 1.新建 C++ Win32项目,类型为DLL. 生 ...

  2. unity调用c++ dll方法介绍

    摘要 unity用的很普遍,现在很多代码还是用c++写的,需要用unity去调用c++的代码.这里介绍了一种unity调用c++ dll的方法,希望有所帮助. 我采用的软件是Visual Studio ...

  3. ocx控件 编译成C#调用的dll 方法 转

      打开VS命令提示行 1.注册ActiveX控件(带上 VCbox.ocx的路径) regsvr32  VCbox.ocx 2.编译OCX文件 aximp VCbox.ocx 生成两个dll文件,项 ...

  4. 2015.5.9 C#编写DLL及C#调用C#DLL

    过程比C#调用VC++dll简单. 一.创建DLL 新建工程,类型选择类库,生成的结果就是dll 注意:在项目属性-应用程序中,注意三个地方,程序集名称和默认命名空间可以调整,但要一致,别的程序调用此 ...

  5. java基础:方法的定义和调用详细介绍,方法同时获取数组最大值和最小值,比较两个数组,数组交换最大最小值,附练习案列

    1. 方法概述 1.1 方法的概念 方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集 注意: 方法必须先创建才可以使用,该过程成为方法定义 方法创建后并不是直接可 ...

  6. 在C#调用C++的DLL方法(二)生成托管的DLL

    写操作之前,还是扼要的说一下托管与非托管C++的区别好了,其实我也并没有深入了解过托管C++的特点所在,其最大的特征就是可以由系统来调试回收相关的代码资源,跟C#的特性一样,只是编程风格跟C++类似而 ...

  7. C# 通过反射类动态调用DLL方法

    网上看了很多关于反射的思路和方法,发现这个还算不错 //使用反射方: using System; using System.Collections.Generic; using System.Linq ...

  8. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  9. go 调用windows dll 的三种方法

    参考:https://blog.csdn.net/qq_39584315/article/details/81287669 大部分代码参考:https://studygolang.com/articl ...

随机推荐

  1. 《C#微信开发系列(4)-接收 / 返回文本消息》

    4.0接收 / 返回文本消息 ①接收/返回文本消息原理说明 当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上,着手开发之前先行阅读微信公众平台接收普通消息 ...

  2. 纯HTML+CSS带说明的黄色导航菜单

    HoverTree带说明的CSS菜单:纯HTML+CSS结构链接带说明的黄色导航 在线体验效果:http://hovertree.com/texiao/css/1.htm 代码如下,保存到HTML文件 ...

  3. npm 入门

    要使用 npm 需要安装 node.js,因为 node.js 中会附带 npm 查看 node 的安装路径 which node 查看 npm 的安装路径 which npm npm 分为两种安装模 ...

  4. Imperva WAF使用笔记

    添加IP白名单 在对自己公司网站进行安全测试时会被WAF拦截,如果把WAF彻底停掉就无法拦截到外部的攻击了. 此时可以添加IP地址白名单,白名单内的IP对网站发起扫描时不会做拦截.

  5. 安卓开发之ListAdapter(一)

    Adapter常用来管理数据,是连接后端数据和前端显示的适配器接口,是数据和UI(view)之间一个重要的纽带.再常见的view(listview.gridview)等地方都需要用到adapter,下 ...

  6. 解决:eclipse删除工程会弹出一个对话框提示“[project_name]”contains resources that are not in sync with"[workspace_name...\xx\..xx\..\xx]"

    提示“[project_name]”contains resources that are not in sync with"[workspace_name...\xx\..xx\..\xx ...

  7. 在Asp.Net MVC中实现计算页面执行时间及简单流量统计

    引用www.rsion.com.dll进您的asp.net MVC项目本人不才,源代码中有详细说明,查看demo修改HomeController public class HomeController ...

  8. 带你一步步的了解“C#事件”机制

    是什么 本文讨论类型中定义的最后一种成员:事件 定义了时间成员的类型允许类型通知其他对象发生了特定的事情. 具体的说,定义了时间成员的类型能提供以下功能: 方法能登记它对事件的关注 方法能注销它对事件 ...

  9. C++基础——模拟事务 (2)Composite模式

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  10. Linux Daemon进程

    模型 创建孤儿进程 fork() 创建新的会话 setid() 改变当前目录为根目录chdir() 重设文件权限掩码umask() 关闭文件描述符close() 创建孤儿进程 创建孤儿进程只需要将父进 ...