最近看到有同学在问C#如何动态加载C的DLL,所以在这里跟大家分享一下!

本文以VS2013来做开发示例,请知悉!(注C#项目仅设置了Debug解决方案,release一样的更改即可)。

如下图,工程分为3个:

TestDLL是导出库,导出 test_hello 函数作为要被加载的测试DLL;

DynamicLoadDemo 为动态加载C#动态加载DLL的方式;(注:LoadLibrary、GetProcAddress、FreeLibrary)

StaticLoadDemo为为静态加载C#动态加载DLL的方式。(注:DllImport)

TestDLL:源码展示

TestDLL.h

#pragma once

#ifdef TESTDLL_EXPORTS
#define TESTDLL_API  _declspec(dllexport)
#else
#define TESTDLL_API _declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"{
#endif
	TESTDLL_API int test_hello();
#ifdef __cplusplus
};
#endif

  

TestDLL.cpp

#include "TestDLL.h"

#ifdef __cplusplus
extern "C"{
#endif
	TESTDLL_API int test_hello()
	{
		::MessageBoxA(NULL,"test_hello","msg",0);
		return 1;
	}
#ifdef __cplusplus
};
#endif

  通过以上代码就顺利的导出了函数test_hello。  depends查看如下图

好了下面我们进入正题:

DynamicLoadDemo :

在C++ 中 使用LoadLibrary、GetProcAddress、FreeLibrary三个函数即可实现DLL的动态加载(不清楚的同学请自动MSDN)。

C#动态load也是用的这3个函数实现,但是C#不提供这些函数的引用方式,那么我们自己就加载系统DLL来获得这三个函数的调用方法!

其实使用的方法也就是DllImport。

如下图

下面是测试代码,测试工程很简单只有一个Button,代码如下

      // int test_hello();
        public delegate int test_hello_fn();
        private void load_click(object sender, EventArgs e)
        {
            Int32 hModule = 0;
            int iResult = 0;
            do
            {
                hModule = CDynamicLoadHelper.LoadLibrary("TestDLL.dll");
                if(0 == hModule)
                {
                    iResult = -1;
                    break;
                }
                //
                IntPtr temp_fn = IntPtr.Zero;
                temp_fn = CDynamicLoadHelper.GetProcAddress(hModule,"test_hello");//get c export fun  test_hello
                if(IntPtr.Zero == temp_fn)
                {
                    iResult = -2;
                    break;
                }
                test_hello_fn fn = (test_hello_fn)Marshal.GetDelegateForFunctionPointer(temp_fn, typeof(test_hello_fn));
                iResult = fn();
            } while (false);
            if(0 != hModule)
            {
                CDynamicLoadHelper.FreeLibrary(hModule);
                hModule = 0;
            }
            MessageBox.Show("test over result is:" + iResult);
        }

StaticLoadDemo:

直接使用C#的DllImport 引入函数,此时Demo提供2中测试方法,一种带异常捕捉,另外一种不带异常捕捉。

load_catch_click(有异常捕捉的)
load_click(无异常捕捉)
    [DllImport("TestDLL.dll", EntryPoint = "test_hello")]
        public static extern Int32 test_hello_fn();
        private void load_catch_click(object sender, EventArgs e)
        {
            int iResult = 0;
            try
            {
                 iResult = test_hello_fn();
            }catch
            {
                iResult = -1;
            }
            MessageBox.Show("test over result is:" + iResult);
        }

        private void load_click(object sender, EventArgs e)
        {
             int   iResult = test_hello_fn();
            MessageBox.Show("test over result is:" + iResult);
        }

运行效果如下:

DynamicLoadDemo.exe:

可以看到第一次弹出的test_hello为DLL弹出的对话框,第二个对话框为C#的结果提示框。

StaticLoadDemo.exe

(略)正常情况下运行情况和DynamicLoadDemo.exe一样(如上图),

正常情况下DLL都被正常加载到了。我们这里做一个特俗的事情,就是把当前目录的TestDLL.dll 删掉。看运行情况会怎么样?

DynamicLoadDemo.exe反映正常没有异常捕捉也发现DLL 不存在,运行结果在意料之中。(没有跑飞)

StaticLoadDemo.exe

有异常捕捉的

没有异常捕捉的

可以看到没有异常捕捉的直接报错了,

文章完!那种加载方式还得看大家的选择,本人对C#仅停留于DEMO层次不评价那种方式更优!

源码包CSDN:http://download.csdn.net/detail/u012251006/9912376

部分信息来源自网上!假如侵犯了你的权利,请告知,我会尽快删除!

时间: 2024-08-02 22:38:49

最近看到有同学在问C#如何动态加载C的DLL,所以在这里跟大家分享一下!的相关文章

Windbg(2)

摘抄于:http://www.cnblogs.com/awpatp/category/228209.html Debug相关的一些小技巧 摘要: 1. 如何Debug一个进程的子进程? 答: 使用WinDBG attach到父进程, 然后输入命令".childdbg 1"(无引号). 这样子进程在刚刚被加载的时候, WinDBG就Attach上去了. 这两个进程的debug session都在一个WinDBG的窗口里, 如果想要切换当前进程, 可以使用命令"|"来查

Android插件化开发之Atlas初体验

OpenAtlas一款强大的Android非代理动态部署框架,目前已经处于稳定定状态. 与传统的代理方式插件不同,OpenAtlas需要对注册动态部署的组件到manifest文件. 初体验,只不过就是把程序跑起来,跑通,后面的路还很长.这个过程中也是遇到了不少问题,刚开始拿到这个项目真是无处下手(没有看到有wiki),后来百度搜索了下找到四篇博文,大概就是OpenAtlas的作者写的吧 Android OpenAtlas初识 Android OpenAtlas之二 基本结构 OpenAtlas之

面试京东Java架构师,竟然被问这些题,学到了!

前言 其实收到jd的面试邀请的时候,我真心有点小激动.因为在地理位置上,jd应该是最合适我也是最想去的.但是我在看到方向的时候其实心里有很多的问题,也做好了被拒的准备. 面试过程及感受 因为是开车去,所以到亦庄的时候第一个问题是找车位,但是京东周边的马路上是基本不可能找到的了,还看到一个司机因为倒车慢了一点,被另外的小车司机迅速停入,吵吵了半天.最后在一个角落找到一个停车场,需要预约码才能停,门口没有任何标志,还是问了门卫大叔才知道一般外来的都会停在这.(jd也是够了..藏得这么隐蔽.还有马路边

个人总结------高级知识点必会

高级知识点之必会 共44题 1.OC中创建线程的方法是什么?如果指定在主线程中执行代码?如何延时执行代码.[难度系数★★] 1)创建线程的方法 NSThread NSOperationQueue和NSOperation GCD 2)主线程中执行代码 [self performSelectorOnMainThread:withObject: waitUntilDone:]; [self performSelector: onThread:[NSThreadmainThread] withObjec

Flume-NG源码分析-整体结构及配置载入分析

在 http://flume.apache.org 上下载flume-1.6.0版本,将源码导入到Idea开发工具后如下图所示: 一.主要模块说明 flume-ng-channels 里面包含了filechannel,jdbcchannel,kafkachannel,memorychannel通道的实现. flume-ng-clients 实现了log4j相关的几个Appender,使得log4j的日志输出可以直接发送给flume-agent:其中有一个LoadBalancingLog4jApp

浅谈HTML5单页面架构(一)——requirejs + angular + angular-route

本文转载自:http://www.cnblogs.com/kenkofox/p/4643760.html 心血来潮,打算结合实际开发的经验,浅谈一下HTML5单页面App或网页的架构. 众所周知,现在移动Webapp越来越多,例如天猫.京东.国美这些都是很好的例子.而在Webapp中,又要数单页面架构体验最好,更像原生app.简单来说,单页面App不需要频繁切换网页,可以局部刷新,整个加载流畅度会好很多. 废话就不多说了,直接到正题吧,浅谈一下我自己理解的几种单页面架构: 1.requirejs

C++培训:C语言链接表分析

C++培训之前有同学再问C语言链接表怎么破?今天小编把这个知识点给大家分享出来,有疑问的可以多看看! 相信学了c语言的人对链表或多或少有了解,链表也是数据结构的重要内容,今天就来聊聊最简单的单向动态链表的建立与输出.首先要了解什么是链表,链表是程序设计中一种重要的动态数据结构,是动态地进行存储分配的一种结构.其中动态主要表现在元素位置可以变化,即随意删除随意插入等;元素个数可增可减,不像数组声明后长度就固定不变了.这就想起前段时间有人在群里问怎么删除素组中任意一个元素,如果没有链表刚开始学感觉就

iOS面试必备-iOS基础知识

近期为准备找工作面试,在网络上搜集了这些题,以备面试之用. 插一条广告:本人求职,2016级应届毕业生,有开发经验.可独立开发,低薪求职.QQ:895193543 1.简述OC中内存管理机制. 答:内存管理机制:使用引用计数管理,分为ARC和MRC,MRC需要程序员自己管理内存,ARC则不需要.但是并不是 所有对象在ARC环境下均不需要管理内存,子线程和循环引用并不是这样.与retain配对使用的是release,retain代表引用计 数+1,release代表引用计数-1,当引用计数减为0时

Web应用的组件化(二)——管控平台 #7

Web应用的组件化(二) 管控平台 在上一篇中我们提到了组件化的大致思路,这一篇主要讲述在这么做之后,我们需要哪些外围手段去管控整个开发过程.从各种角度看,面对较大规模前端开发团队,都有必要建立这么一个开发阶段的协作平台. 在这个平台上,我们要做哪些事情呢? 1. HTML片段 我们为什么要管理HTML片段?因为有界面要用它们,当这些片段多了之后,需要有个地方来管理起来,可以检索.预览它们,还能看到大致描述. 这应该是整个环节中一个相对很简单的东西,照理说,有目录结构,然后剩下的就是单个的HTM