C# 运行时调用dll、dll中对象、对象中方法等

UnityResolve.hpp:C++调用Unity C#对象的桥接库实战指南 在游戏开发与逆向工程中,跨语言调用是连接不同技术栈的核心需求。其原理在于通过运行时反射或API封装,实现内存层面的数据交换与函数调用,从而突破语言壁垒。这种桥接技术的价值在于极大简化了混合编程的复杂度,提升了开发效率与代码可维护性。典型的应用场景包括游戏Mod开发、辅助工具编写、自动化测试以及安全分析,开发者需要在C++等原生语言中便捷地操作Unity引擎的C#托管对象。UnityResolve.hpp正是针对这一场景的解决方案,它是一个纯头文件的C++库,通过对Mono或IL2CPP运行时的高级封装,提供 阅读详情

//dll

namespace Dynamic_linking
{
    public partial class ShowErrorForm : Form
    {
        public ShowErrorForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("It is children!");
        }
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

//controller

namespace Mainform
{
    public class LDFS
    {
        // 记录要导入的程序集
        static Assembly MyAssembly;
        /// <summary>
        /// 添加LoadDll方法
        /// </summary>
        /// <param name="lpFileName"></param>
        /// <returns></returns>
        private byte[] LoadDll(string lpFileName)
        {
            Assembly NowAssembly = Assembly.GetEntryAssembly();
            Stream fs = null;
            try
            {// 尝试读取资源中的 DLL 同一命名空间下
                fs = NowAssembly.GetManifestResourceStream(NowAssembly.GetName().Name + "." + lpFileName);
            }
            finally
            {// 如果资源没有所需的 DLL ,就查看硬盘上有没有,有的话就读取
                if (fs == null && !File.Exists(lpFileName))
                    throw (new Exception(" 找不到文件 :" + lpFileName));
                else if (fs == null && File.Exists(lpFileName))
                {
                    FileStream Fs = new FileStream(lpFileName, FileMode.Open);
                    fs = (Stream)Fs;
                }
            }
            byte[] buffer = new byte[(int)fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
            return buffer; // 以 byte[] 返回读到的 DLL
        }
        /// <summary>
        /// 添加UnLoadDll方法来卸载DLL
        /// </summary>
        public void UnLoadDll()
        {// 使 MyAssembly 指空
            MyAssembly = null;
        }

        /// <summary>
        /// 添加Invoke方法来进行对DLL中方法的调用
        /// </summary>
        /// <param name="lpFileName">dll名称</param>
        /// <param name="Namespace">命名空间</param>
        /// <param name="ClassName">类名</param>
        /// <param name="lpProcName">调用函数的名称</param>
        /// <param name="ObjArray_Parameter">参数</param>
        /// <returns></returns>
        public object Invoke(string lpFileName, string Namespace, string ClassName, string lpProcName, object[] ObjArray_Parameter)
        {
            try
            {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集
                if (MyAssembly == null || MyAssembly.GetName().Name != Namespace)
                    MyAssembly = Assembly.Load(LoadDll(lpFileName));
                Type[] type = MyAssembly.GetTypes();
                foreach (Type t in type)
                {
                    if (t.Namespace == Namespace && t.Name == ClassName)
                    {
                        MethodInfo m = t.GetMethod(lpProcName);
                        if (m != null)
                        {// 调用并返回
                            object o = Activator.CreateInstance(t);
                            return m.Invoke(o, ObjArray_Parameter);
                        }
                        else
                            System.Windows.Forms.MessageBox.Show(" 装载出错 !");
                    }

                }

            }
            catch (System.NullReferenceException e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
            return (object)0;
        }

        public object Invoke(string lpFileName, string Namespace, string ClassName)
        {
            try
            {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集
                if (MyAssembly == null || MyAssembly.GetName().Name != Namespace)
                    MyAssembly = Assembly.Load(LoadDll(lpFileName));
                Type type = MyAssembly.GetType(Namespace + "." + ClassName);
                if (type.Namespace == Namespace && type.Name == ClassName)
                {
                    object classobj = Activator.CreateInstance(type);
                    return classobj;
                }
                else
                    System.Windows.Forms.MessageBox.Show(" 命名空间或类名错误 !");

            }
            catch (System.NullReferenceException e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
            return (object)0;
        }
    }
}

//调用

public partial class Mainform : Form
    {
        public Mainform()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LDFS myldfs = new LDFS();
            object myobj = myldfs.Invoke("Dynamic_linking.dll", "Dynamic_linking", "ShowErrorForm");
            ((Form)myobj).Show();
            #region --加载dll--
            //利用反射进行动态加载和调用.
            //Assembly ass = Assembly.LoadFrom(Environment.CurrentDirectory + "//Dynamic_linking.dll"); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll
            ////Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名

            ////加载dll后,需要使用dll中某类.
            //Type type = ass.GetType("Dynamic_linking.ShowErrorForm");//利用类型的命名空间和名称获得类型

            ////需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略
            //Object obj = Activator.CreateInstance(type, null);//利用指定的参数实例话类型
            //((Form)obj).Show();
            //调用类型中的某个方法:
            //需要首先得到此方法
            //MethodInfo mi = type.GetMethod("Add");//通过方法名称获得方法

            //然后对方法进行调用,多态性利用参数进行控制
            //object myobj = mi.Invoke(obj, new object[]{2,3});//根据参数直线方法,返回值就是原方法的返回值
            #endregion
        }

 

避坑指南:VS2022调用C# DLL常见的5个错误及解决方法 本文针对Visual Studio 2022开发环境中调用C# DLL时常见的五大难题,提供了精准的解决方案。重点剖析了因平台架构不匹配导致的“BadImageFormatException”错误,并详细解释了如何通过统一项目配置来根治此问题。同时,指南还涵盖了DLL加载路径、版本依赖冲突、强名称签名验证以及方法调用可见性等高频陷阱,帮助开发者高效排雷,确保C# DLL调用过程顺畅无误。 阅读详情

相关推荐

C++调用C# DLL的混合编程实践与优化

混合编程是现代软件开发中的常见需求,特别是在需要结合不同语言优势的场景下。通过CLR(Common Language Runtime)的跨语言互操作特性,C++可以高效调用C#编写的功能模块。这种技术方案在遗留系统集成、性能关键型应用和第三方组件复用等场景中具有显著价值。以C++/CLI作为桥接层,开发者既能保持C++的性能优势,又能利用.NET丰富的类库生态。实际应用中需要注意类型安全、内存管理和调试技巧,例如通过混合模式调试和内存泄漏检测来确保系统稳定性。对于需要频繁调用的场景,建议采用对象池和预加载策

weixin_27219587的博客 351

C#引用dll文件路径问题(查找DLL顺序 bin/system/env)

在调用非托管的DLL文件时,.net是无法引用的,这个时候我们就需要用到DllImport来引用(using System.Runtime.InteropServices)dll文件。 DllImport引用dll的路径查找顺序是首先从当前应用程序bin目录,然后system32文件夹下面寻找,接着是环境变量。 一般我放在bin目录下面,但是这个时候有问题时就是dll可能会重名 解决方法: ...

qq_37871669的博客 3727

C#调用C++的dll方法

C#调用C++的dll总归可以有两种方法: 1、非托管C++创建的dll库,需要用静态方法调用; 2、直接使用CLR,生成托管C++dll库。

欧特GO 7万+

如何利用C#创建和调用DLL

 一、写在前面C# 语言是一种简单但功能强大的编程语言,用于编写企业应用程序。 C# 语言从C和 C++语言演化而来,在语句、表达式和运算符方面使用了许多 C++ 功能。C# 语言在类型安全性、版本转换、事件和垃圾回收等方面进行了相当大的改进和创新。C# 语言提供对常用 API 样式(如 .NET 框架、COM、自动化和 C 样式 API 等)的访问。       什么是动态链

无轩居 (Home of vip) 2211

C#热更原理:为何原生不支持DLL替换?

原生动态加载新程序集使用其中的类型和方法卸载已加载的程序集把“同名类型”当作同一个类型,并自动替换让某个类型的所有现有实例换成新实现这已经把一个重要结论摆出来了:单纯从“加载 DLL”这个动作本身,你是拿不到“平滑替换逻辑”的能力的。真要做热更,必须搞一套自己的“中间层/解释器/代理层”不能直接用底层 CLR 的原始模型。把最容易变的逻辑写成脚本脚本每次运行时解析/编译/解释旧脚本不用了就丢,新脚本读进来就行C# 做的是“脚本宿主”,脚本层才是“热更层”。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 77

鼎捷T100——二次开发:维护作业添加非实体字段

非实体字段添加

weixin_52342654的博客 1160

C#执行某对象的某个方法

3.委托调用方法:在C#中,可以使用委托调用方法。委托是一种类型,它封装了一个或多个方法,并允许将这些方法作为参数传递给其他方法或存储在变量中。需要注意的是,使用反射调用方法可能会降低程序的性能,因为它需要在运行时进行类型信息的获取和方法调用的解析。需要注意的是,委托类型必须与要封装的方法具有相同的签名,即参数列表和返回类型都必须匹配。1.直接调用方法:如果我们有一个对象,并且知道它的方法名称和参数列表,那么可以直接调用该方法。,它封装了一个方法,该方法接受一个字符串类型的参数并返回void。

beenles的博客 826

AI 赋能测试全生命周期:多 Agent 协同的自动化提效方案

本文提出了一种基于Coze平台的多Agent协同测试解决方案,旨在解决软件测试中PRD解析不清晰、测试点覆盖不全、用例编写效率低、代码生成耗时等痛点。通过PRD优化、测试点生成、测试用例生成和单元测试框架生成四个Agent的协同工作,结合Cursor工具实现从需求到代码的全链路自动化。以电商平台登录模块为例,展示了从模糊PRD到标准化测试用例和可执行Java单元测试代码的完整转化流程。该方案通过AI赋能显著提升测试效率,减少人工干预,实现测试覆盖率≥95%,为快速迭代的软件研发提供了高效的测试自动化支持。

QINJIEEE的博客 1102

C# 获取当前方法的调用者

/// <summary> /// Caller method full name: namespace.class.method /// </summary> /// <returns></returns> public static string GetCallerName() { // 0: current method, i.e. GetCallerName // 1: 1 frame up current method: the m.

David 2100

Kriging代理模型理论相关推导

代理模型,Kriging,加点准则

森屹的博客 1万+

CPU核心、die和package的区别:从硬件小白到高手的进阶指南

本文深入浅出地解析了CPU核心、Die与Package的核心概念与区别,是硬件爱好者从入门到精通的实用指南。文章从硅晶圆制造讲起,阐述了物理核心与逻辑线程(如超线程技术)的工作原理,并详细介绍了封装(Package)的作用与多Die模块化设计。最后,结合实际应用场景,提供了选购、性能解读与优化调优的实用建议。

pz89012345的博客 203

C# 获取调用方信息

using   System; using   System.Diagnostics; using   System.Reflection; namespace   MyTest {     public   class   TestM     {     public   void   Test() { StackFrame   fr   =   new   Stack...

weixin_33830216的博客 205

易灵思FPGA-软件Efinity和Modelsim联仿设置

文章目录前言一、modelsim破解过程二、使用步骤1.引入库2.读入数据总结欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智

qq_35221855的博客 5362

【C# 】反射,调用.dll文件里面的方法

C# 反射朝夕教育vip班个人笔记文章介绍开源资源连接泛型方法的声明与调用 文章介绍 学习笔记,基于朝夕教育VIP班课程 文章主要讲了:泛型约束, 文章写的不好,自己看 开源资源连接 源码地址,推荐直接看源码 泛型方法的声明与调用 ...

Liaiblog 3347

MobaXterm简介和使用(服务器连接工具)

MobaXterm 是一个功能强大的远程计算工具,集成了许多常用的远程计算功能,包括 SSH、X11、RDP、VNC、FTP、SFTP 等。

清平乐的技术专栏 1950

AD(Altium Designer)器件封装——立创商城导出原理图和PCB完成器件封装操作指南

官网:www.SZLCSC.COM以芯片为例器件类——>芯片类——>对应芯片确定芯片——>数据手册1:原理图2:PCB3:打开操作流程选中原理图——>文件——>导出——>AD1: ✔2:导出AD文件操作流程选中PCB图——>文件——>导出——>AD1: ✔2:导出AD文件1:PCB图2:原理图操作流程文件——>打开操作流程选中文件——>打开操作流程项目文件——>添加新的...到工程——>Schematic Library新原理图库操作流程项目文件——>添加新的...到工程——>PCB Library新的PC

XU157303764的博客 5437

C#反射实例讲解

 1 创建用于反射使用的DLL新建一个C#类库项目,拷贝源代码如下,编译生成DLL(假如DLL的文件名是TestReflect.dll)  1using System; 2 3namespace Webtest 4{ 5 /**////  6 /// ReflectTest 的摘要说明。 7 ///  8 public class ReflectTest 9 {10  public Ref

Akuma专栏 1274

SAP 的预算控制并非单一功能,而是根据管控的精细度和业务场景,主要通过三个模块实现:CO(成本控制)、FM(基金管理) 和 PS(项目系统)

SAP系统提供三种预算控制模型:基于CO模块的成本中心/内部订单预算管控,适用于日常费用管理;基于FM模块的基金中心/承诺项目预算控制,满足公共部门严格资金管理需求;基于PS模块的WBS元素预算控制,专为项目型企业设计。各模型通过特定配置实现预算编制、审批、控制和分析功能,并配有核心事务代码(T-Code)支持全流程操作。企业可根据业务场景选择适合的预算控制方式,实现从预算编制到执行监控的闭环管理。

金牌架构师 253

C# 反射(Reflection)

反射主要用于在程序运行期间动态解析相关类的类名,命名空间,属性,方法并进行相应操作,以下通过两个简单的例子进行了说明: 示例1:调用程序集内部方法,运行时动态获取相关类的信息,包括类名,命名空间等信息并进行对象的创建及方法的调用: 测试类: class HI { public string Hi = "HelloWorld"; public string S...

weixin_30425949的博客 123

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

c++托管使用c#动态库

拿来一个dll,是c#编译的,我在c++程序中需要使用该dll,网上查了相关资料,需要用到 c++托管相关知识,即CLR公共语言时运行环境。具体使用步骤如下:           1.拷贝dll到工程运行目录下。     2.引用:            #using \"..\\debug\\CTest.dll\"          using namespace CTest;

超哥的专栏 2709

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C#——反射

反射是 C# 提供的一种 在运行时动态获取类型信息、创建对象、调用方法或访问字段/属性 的机制。遇到访问私有成员,需要设置 BindingFlags.NonPublic;反射比普通代码慢(涉及元数据解析),尽量不要频繁使用;🧱 一、准备插件 DLL(MyPlugin.dll)🧪 五、进阶使用:从 DLL 加载类并调用方法。🧠 一、什么是反射(Reflection)但在 运行时,你可以用反射获取并操作它们。使用反射前建议明确目标,反射不是银弹。编译时你不清楚具体类型/方法是什么,🎯 四、实例讲解(一步

m0_51489204的博客 456

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C# 反射的使用

C# 反射的使用

廷益_飞鸟的博客 260

一个浅显易懂的反射例子

反射,就是程序集的一面镜子,所以才叫反射.废话少说,以一个简单的例子切入正题吧:1 创建用于反射使用的DLL 新建一个C#类库项目,拷贝源代码如下,编译生成DLL(假如DLL的文件名是TestReflect.dll)代码如下: using System;namespace Webtest{    /**//// &lt;summary&gt;    /// Summary description...

weixin_33790053的博客 155

《C#从现象到本质》读书笔记(八)第10章反射

《C#从现象到本质》读书笔记(八)第10章反射 个人感觉,反射其实就是为了能够在程序运行期间动态的加载一个外部的DLL集合,然后通过某种办法找到这个DLL集合中的某个空间下的某个类的某个成员(通过反射可以访问该类所包含的所有成员,不论成员是公有还是私有)。 在.NET中,查看和操作元数据的动作,称为反射。 通过反射我们可以:1)加载一个程序集,这称为动态加载程序集或者晚期绑定。2)获得程序集...

weixin_30566149的博客 364

在C++ 中 如何调用 C# 写的DLL

对于很多和我一样的老C++程序员来讲,如果不能与时俱进,不但会倍感失落,还会真的自绝于天下。    比如C#有很多好的组件, 如NPOI ,如。。。,怎么在C++中也自如调用呢,这样不用去学习C#,不用换刀,也可以达到同样的目的。 网上看了半天,找到的资料要么太老,要么不对,干脆自己调试一遍。下面把体会说一说。 调试环境:visual studio 2010 . 时间:2012.12.20

GYY_2046的博客 797

C#反射动态调用dll中的方法,并返回结果[转]

最近在看工厂开发模式,发现用到了反射,之前只听说过也没怎么用过;所以花了点时间重新温习了一遍; 反射的作用是动态的加载某个dll(程序集),并执行该程序集中的某个方法,并返回结果;当然也可以给该方法传递参数 namespace assembly_name { public class assembly_class { ...

weixin_30552811的博客 117
上一篇: php basic.php
下一篇: js 弹出窗口
andycode
博客等级 码龄17年 12粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值