`

C#动态调用C++生成的dll

阅读更多
C++中的方法int MyFun(int a,int b);
生成dll文件:MyDll.dll

在C#中调用dll文件一般需要声明:
    [DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int MyFun( int a, int b);
这样想动态来加载dll没办法操作。

后来在网上查了下,有两种方式能够动态的加载dll,不用声明:

先准备好DllInvoke类
 public class DllInvoke
    {
        #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);
            if (hLib == IntPtr.Zero)
            {
                throw (new Exception("没有找到:" + DLLPath + "。"));
            }  
        }

        ~DllInvoke()
        {
            FreeLibrary(hLib);
        }
        public IntPtr GetIntPtr(string APIName)
        {
            IntPtr api = GetProcAddress(hLib, APIName); 
            if (api == IntPtr.Zero)
            {
                throw (new Exception(" 没有找到 :" + APIName + " 这个函数的入口点 "));
            } 
            return api;
        }
        //将要执行的函数转换为委托
        public Delegate GetDelegate(string APIName, Type t)
        {
            IntPtr api =GetIntPtr(APIName);
            return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t);
        }
    }



方法一:
delegate int Add(IntPtr[] X, int r, int c);

 
 DllInvoke dk = new DllInvoke("MyDll.dll");
 Add addFunction = (Add)dk.GetDelegate("MyFun", typeof(Add));
int sum=addFunction(2,3);



方法二:
object[] par = new object[] {2,3 };//输入参数
Type[] parType = par.Select(s=>s.GetType()).ToArray();//输入参数的类型
//Type[] parType =new Type[]{typeof(int),typeof(int)};
Type Type_Return = typeof(int); // 返回类型
 
AssemblyName assemblyName = new AssemblyName("InvokeName");//名称随便写
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("InvokeModule");
MethodBuilder methodBuilder = moduleBuilder.DefineGlobalMethod("InvokeMethod", MethodAttributes.Public | MethodAttributes.Static, Type_Return, parType);
ILGenerator IL = methodBuilder.GetILGenerator();
for (int i = 0; i < par.Length; i++)
           {// 依次压入堆栈  
               IL.Emit(OpCodes.Ldarg, i);   //实参传送方式,byValue 
               //    IL.Emit(OpCodes.Ldarga, i);//实参传送方式,byRef 
           }
//要调用的dll
           DllInvoke dk = new DllInvoke("MyDll.dll");
//调用的方法
           IntPtr farProc = dk.GetIntPtr("MyFun");
           if (IntPtr.Size == 4)
           {// 判断处理器类型
               IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32());
           }
           else if (IntPtr.Size == 8)
           {
               IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64());
           }
           else
           {
               throw new PlatformNotSupportedException();
           }
           IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, Type_Return, parType);
           IL.Emit(OpCodes.Ret);
           moduleBuilder.CreateGlobalFunctions();
//方法名和上面的一致
           MethodInfo MyMethodInfo = moduleBuilder.GetMethod("InvokeMethod");
           object sum = MyMethodInfo.Invoke(null, par);// 调用方法,并返回其值

分享到:
评论

相关推荐

    C#动态调用C++生成dll文件,区别于添加引用方式。

    本文将深入探讨如何在C#项目中动态地调用C++生成的DLL文件,以及这种方式与直接添加引用的区别。 首先,我们理解标题指出的问题:在C#中尝试直接添加C++生成的DLL作为引用时,可能会遇到兼容性问题导致报错。这是...

    C#调用C++的动态库Dll示例(含UsbLibDotNet使用)

    1.C#调用C++封装的动态库dll 2.结构体含union共同体的C++转C#示例 3.C#结构体指针的调用演示 4.C#读取USB数据设备的示例 5.C#动态调用C++dll库示例 6.C#静态调用C++dll库示例 注意:UsbLibDotNet使用时候需要先安装...

    C#调用C++动态DLL

    在C#中调用C++编写的动态链接库(DLL)是一种常见的跨语言通信方式,特别是当C++库提供了某些C#中没有的功能或者优化的性能时。本文将详细探讨如何在C#中实现对C++动态DLL的调用。 首先,了解动态链接库(DLL)的...

    c#调用c++DLL,dll有二维数组

    标题中的“c#调用c++DLL,dll有二维数组”意味着我们将在C++的DLL中定义一个二维数组,然后在C#中调用该函数并处理这个数组。在C++中,二维数组通常以指针的形式传递,因为C++不支持引用参数。而在C#中,我们通常...

    C#Winform动态调用C++和C#的Dll

    本文将重点讲解如何在C#的Winform应用中动态调用C++和C#编写的DLL,并将DLL作为嵌入资源处理,避免因丢失DLL文件而引发的问题。 首先,我们需要理解DLL的工作原理。DLL文件包含可执行代码和数据,当一个应用程序...

    c#调用c++生成的dll文件中类方法

    总结来说,C#调用C++生成的DLL中的类方法涉及到跨语言互操作,通常需要通过C风格接口或C++/CLI作为中介。理解这两种方法的工作原理和限制,对于有效地在C#项目中集成C++代码至关重要。在实际开发中,需要根据项目的...

    C#【必备技能篇】VS2019 使用C/C++ 生成DLL 文件,并用 C/C++、C#调用DLL

    在C#开发软件的过程中,要经常调用C/C++生成的dll,本文主要介绍用C/C++生成dll的步骤,以及用C/C++、C#两种语言实现dll的引用实现。本文使用的IDE是VS2019,文章通过具体实例进行讲解,大家可以跟着自己动手进行...

    C#使用CLR调用C++的DLL库

    本主题将详细介绍如何在C#应用中利用CLR调用C++编写的DLL库,特别是在Windows环境下。我们将分为三个关键步骤进行讲解: 1. **创建C++ DLL库** - 首先,你需要创建一个C++动态链接库(DLL)项目。在Visual Studio...

    C#调用C++DLL导出类

    总结来说,C#调用C++DLL中的类主要涉及以下几个步骤: 1. 在C++DLL中定义导出类及其方法。 2. 在C#中使用DllImport加载DLL,并定义C风格的函数接口。 3. 创建一个C#托管类,持有C++对象的指针,并提供相应的C#方法...

    C#调用C++DLL动态库.rar_C#调用C++DLL动态库_c++dll动态库_c++开发动态库

    C#调用C++ DLL时可能会遇到异常,例如找不到DLL或函数,或者参数不匹配。因此,需要适当的错误处理机制,例如使用`try-catch`块。 7. **平台兼容性**: 跨平台开发时,需要注意C++ DLL是否适用于目标平台(如x86...

    C#调用C++项目生成的dll文件

    接下来,是C#调用C++ DLL的关键步骤: 1. 引用DLL:在C#项目中,需要使用`using System.Runtime.InteropServices;`命名空间,这是.NET Framework提供的互操作性支持。然后,使用`[DllImport]`特性声明DLL,并指定...

    C#调用C++生成的Dll文件源码

    本示例中的“C#调用C++生成的Dll文件源码”展示了如何通过C#程序调用C++编译的动态链接库(Dll)。下面我们将详细探讨这一过程的关键知识点。 首先,C++生成Dll项目。在C++中,创建Dll文件通常涉及以下步骤: 1. ...

    C#调用 C++dll(包含传递自定义结构数组)

    当C#调用C++dll时,需要传递自定义结构的数组,该怎么办? 示例给出了方案

    C#调用C++的DLL

    在.NET框架中,C#是一种常用的...总的来说,C#调用C++DLL涉及了P/Invoke、数据类型映射、错误处理等多个方面,理解这些概念和技巧对于跨语言编程至关重要。实际操作时,还需要根据具体DLL的接口和需求进行适配和调整。

    C#调用C++ Dll关于结构体数组引用的传递及解析使用的展示代码

    ### C#调用C++ DLL:结构体数组引用的传递及解析使用详解 #### 引言 在跨语言编程环境中,经常会遇到不同编程语言之间进行交互的需求。C#与C++之间的互操作就是一个典型场景。当C#需要调用C++开发的动态链接库...

    C#调用C++生成的DLL,并返回结构体引用或者结构体指针多个值

    总结,C#调用C++生成的DLL返回结构体引用或指针,主要涉及结构体的定义、`DllImport`特性的使用、内存管理和错误处理。通过正确的映射和转换,可以无缝地在C#和C++之间传递结构体数据,实现跨语言的高效协作。

    c#调用c++ dll 传参 string 崩溃的一种解决办法

    一个常见的场景是C#调用C++编写的动态链接库(DLL)。然而,在这种情况下可能会遇到一些问题,比如当向C++ DLL传递字符串参数时程序崩溃的情况。本文将详细探讨这一问题,并提供一种可能的解决方案。 #### 问题背景...

    c# 调用C++编写 的DLL函数各种参数传递问题。

    C# 调用 C++ 编写的 DLL 函数各种参数传递问题 在 C# 调用 C++ 编写的 DLL 函数时,参数传递是一个非常重要的部分。这篇文章将详细介绍 C# 调用 C++ 编写的 DLL 函数各种参数传递问题,包括不返回值的参数、带...

    C# 调用C++DLL(函数参数包含指针)

    总结来说,C#调用C++DLL并处理指针参数涉及到P/Invoke、函数原型声明、指针类型映射、内存管理和异常处理等多个环节。理解这些细节是成功进行跨语言互操作的关键。在实际开发中,务必确保所有操作都遵循安全规范,以...

    C++/ C#生成dll 用C/C#/Python/Unity 调用

    VS2015工程里面通过c++生成静态库lib,C++生成dll用C++工程,python, unity调用对应的dll。C#生成 dll,通过C#和Unity工程调用对应的dll。Python使用的是VS中集成Python. Python调用C#dll时需要通过pip安装python...

Global site tag (gtag.js) - Google Analytics