其中要使用两个未公开的Win32 API函数来存取控制台窗口,这就需要使用动态调用的方法,动态调用中使用的Windows API函数主要有三个,即:Loadlibrary,GetProcAddress和Freelibrary。步骤如下:

1.   Loadlibrary: 装载指定DLL动态库

2.   GetProcAddress:获得函数的入口地址

3.   Freelibrary: 从内存中卸载动态库

但是C#中是没有函数指针,无法直接使用GetProcAddress返回的入口地址。后来找到资料,其实.NET 2.0新增了Marshal.GetDelegateForFunctionPointer 方法可以满足这个要求,MSDN里的解释是:将非托管函数指针转换为委托。

后面的事就简单啦,我把它编成了一个类来方便调用。

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace feiyun0112.cnblogs.com
{
public class DllInvoke
{ Win API#region Win API
[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);
#endregion 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);
} }
}

下面是使用代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using feiyun0112.cnblogs.com; namespace ConsoleApplication1
{
class Program
{ public delegate string Test(string a); static void Main(string[] args)
{
DllInvoke dll = new DllInvoke("test2.dll");
Test test = (Test)dll.Invoke("testC", typeof(Test));
string s = test("ss");
Console.WriteLine(s); Console.WriteLine("****************************************");
Console.ReadLine(); }
}
}

DllImport会按照顺序自动去寻找的地方:
1、exe所在目录
2、System32目录
3、环境变量目录
所以只需要你把引用的DLL 拷贝到这三个目录下 就可以不用写路径了

C#中动态调用DLL动态链接库的更多相关文章

  1. C#中动态调用DLL动态链接库(转)

    本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347). 其中要使用两个未公开的 ...

  2. 在Delphi中静态调用DLL

    在Delphi中静态调用DLL top 调用一个DLL比写一个DLL要容易一些.首先给大家介绍的是静态调用方法,稍后将介绍动态调用方法,并就两种方法做一个比较.同样的,我们先举一个静态调用的例子. u ...

  3. C#中调用Dll动态链接库

    C#中调用Dll动态链接库 起始 受限于语言的不同,我们有的时候可能会用别人提供的函数及方法 或者其他的什么原因.反正就是要调!!! 恰巧别人所使用的的语言跟自己又不是一样的 这个时候想要调用别人的函 ...

  4. C# 中静态调用C++dll 和C# 中动态调用C++dll

    在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能 ...

  5. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  6. 【VB技巧】VB静态调用与动态调用dll详解

    本文“[VB技巧]VB静态调用与动态调用dll详解”,来自:Nuclear'Atk 网络安全研究中心,本文地址:http://lcx.cc/?i=489,转载请注明作者及出处! [[请注意]]:在以下 ...

  7. C#程序实现动态调用DLL的研究[转]

    摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...

  8. C#程序实现动态调用DLL的研究

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  9. 卸载AppDomain动态调用DLL异步线程执行失败

    应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...

随机推荐

  1. Java线程-volatile不能保证原子性

    下面是一共通过volatile实现原子性的例子: 通过建立100个线程,计算number这个变量最后的结果. package com.Sychronized; public class Volatil ...

  2. 【微软100题】定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。 如把字符串abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。

    package test; /** * 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部. 如把字符串abcdef左旋转2位得到字符串cdefab. 请实现字符串左旋转的函数. * ...

  3. javascript通用函数库

    /* -------------- 函数检索 -------------- trim函数:                         trim() lTrim() rTrim() 校验字符串是否 ...

  4. linux 源码安装 Nginx

    1.安装前环境准备安装make:# yum -y install gcc automake autoconf libtool make安装g++:# yum install gcc gcc-c++ 2 ...

  5. 停掉一台服务器,Nginx响应慢(转载)

    测试发现的问题及解决办法 1.当后端两台IIS应用服务器都正常时,访问速度非常快,查看日志,原来一个请求,是后端两台服务器同时响应的; 2.为了模仿故障测试,停掉一台IIS应用服务器,这时再访问,请求 ...

  6. AngularJS 路由:ng-route 与 ui-router

    AngularJS的ng-route模块为控制器和视图提供了[Deep-Linking]URL. 通俗来讲,ng-route模块中的$routeService监测$location.url()的变化, ...

  7. atitit.面向过程的编程语言异常处理 c语言 asp vbs 的try catch 实现

    atitit.面向过程的编程语言异常处理 c语言 asp vbs 的try catch 实现 1. 返回值法.and全局ERROR 变量法 1 2. 抛出异常Err.Raise 1 3. 实现try  ...

  8. 【Android】13.1 用Android自带的API访问SQLite数据库

    分类:C#.Android.VS2015: 创建日期:2016-02-26 一.简介 这一节我们先来看看如何直接用Android自带的API创建和访问SQLite数据库. 1.创建SQLite数据库 ...

  9. Java常量池解析与字符串intern简介

    在Java应用程序运行时,Java虚拟机会保存一份内部的运行时常量池,它区别于class文件的常量池,是class文件常量池映射到虚拟机中的数据结构. 关于class文件常量池的部分可以参考之前的博文 ...

  10. 人工打jar包

    (一)将可执行程序打成一个jar包 其中Yoyo为入口程序,因此将当前目录下workhard和Book.class.testEx.class.Yoyo.class打成一个jar包的命令如下: jar ...