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作为引用时,可能会遇到兼容性问题导致报错。这是...
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#中没有的功能或者优化的性能时。本文将详细探讨如何在C#中实现对C++动态DLL的调用。 首先,了解动态链接库(DLL)的...
标题中的“c#调用c++DLL,dll有二维数组”意味着我们将在C++的DLL中定义一个二维数组,然后在C#中调用该函数并处理这个数组。在C++中,二维数组通常以指针的形式传递,因为C++不支持引用参数。而在C#中,我们通常...
本文将重点讲解如何在C#的Winform应用中动态调用C++和C#编写的DLL,并将DLL作为嵌入资源处理,避免因丢失DLL文件而引发的问题。 首先,我们需要理解DLL的工作原理。DLL文件包含可执行代码和数据,当一个应用程序...
总结来说,C#调用C++生成的DLL中的类方法涉及到跨语言互操作,通常需要通过C风格接口或C++/CLI作为中介。理解这两种方法的工作原理和限制,对于有效地在C#项目中集成C++代码至关重要。在实际开发中,需要根据项目的...
在C#开发软件的过程中,要经常调用C/C++生成的dll,本文主要介绍用C/C++生成dll的步骤,以及用C/C++、C#两种语言实现dll的引用实现。本文使用的IDE是VS2019,文章通过具体实例进行讲解,大家可以跟着自己动手进行...
本主题将详细介绍如何在C#应用中利用CLR调用C++编写的DLL库,特别是在Windows环境下。我们将分为三个关键步骤进行讲解: 1. **创建C++ DLL库** - 首先,你需要创建一个C++动态链接库(DLL)项目。在Visual Studio...
总结来说,C#调用C++DLL中的类主要涉及以下几个步骤: 1. 在C++DLL中定义导出类及其方法。 2. 在C#中使用DllImport加载DLL,并定义C风格的函数接口。 3. 创建一个C#托管类,持有C++对象的指针,并提供相应的C#方法...
C#调用C++ DLL时可能会遇到异常,例如找不到DLL或函数,或者参数不匹配。因此,需要适当的错误处理机制,例如使用`try-catch`块。 7. **平台兼容性**: 跨平台开发时,需要注意C++ DLL是否适用于目标平台(如x86...
接下来,是C#调用C++ DLL的关键步骤: 1. 引用DLL:在C#项目中,需要使用`using System.Runtime.InteropServices;`命名空间,这是.NET Framework提供的互操作性支持。然后,使用`[DllImport]`特性声明DLL,并指定...
本示例中的“C#调用C++生成的Dll文件源码”展示了如何通过C#程序调用C++编译的动态链接库(Dll)。下面我们将详细探讨这一过程的关键知识点。 首先,C++生成Dll项目。在C++中,创建Dll文件通常涉及以下步骤: 1. ...
当C#调用C++dll时,需要传递自定义结构的数组,该怎么办? 示例给出了方案
在.NET框架中,C#是一种常用的...总的来说,C#调用C++DLL涉及了P/Invoke、数据类型映射、错误处理等多个方面,理解这些概念和技巧对于跨语言编程至关重要。实际操作时,还需要根据具体DLL的接口和需求进行适配和调整。
### C#调用C++ DLL:结构体数组引用的传递及解析使用详解 #### 引言 在跨语言编程环境中,经常会遇到不同编程语言之间进行交互的需求。C#与C++之间的互操作就是一个典型场景。当C#需要调用C++开发的动态链接库...
总结,C#调用C++生成的DLL返回结构体引用或指针,主要涉及结构体的定义、`DllImport`特性的使用、内存管理和错误处理。通过正确的映射和转换,可以无缝地在C#和C++之间传递结构体数据,实现跨语言的高效协作。
一个常见的场景是C#调用C++编写的动态链接库(DLL)。然而,在这种情况下可能会遇到一些问题,比如当向C++ DLL传递字符串参数时程序崩溃的情况。本文将详细探讨这一问题,并提供一种可能的解决方案。 #### 问题背景...
C# 调用 C++ 编写的 DLL 函数各种参数传递问题 在 C# 调用 C++ 编写的 DLL 函数时,参数传递是一个非常重要的部分。这篇文章将详细介绍 C# 调用 C++ 编写的 DLL 函数各种参数传递问题,包括不返回值的参数、带...
总结来说,C#调用C++DLL并处理指针参数涉及到P/Invoke、函数原型声明、指针类型映射、内存管理和异常处理等多个环节。理解这些细节是成功进行跨语言互操作的关键。在实际开发中,务必确保所有操作都遵循安全规范,以...
VS2015工程里面通过c++生成静态库lib,C++生成dll用C++工程,python, unity调用对应的dll。C#生成 dll,通过C#和Unity工程调用对应的dll。Python使用的是VS中集成Python. Python调用C#dll时需要通过pip安装python...