c#引入dll文件报错_C#调用DLL库的方法

本文介绍了如何在C#中调用C++编写的DLL库,包括静态和动态调用两种方式。静态调用需要在C#中使用DllImport进行声明,动态调用则通过LoadLibrary、GetProcAddress等方法实现。文中还提到了注意事项,如DLL文件位置、平台目标设置以及数据类型的互操作性问题。
摘要由CSDN通过智能技术生成

最近工作需要使用C#调用DLL,公司代码不能公开就转载加一些自己的笔记记录一下。使用软件VS2008和VS2017。

1 C#静态调用DLL

1.1  建立VC工程CppDemo,建立的时候选择Win32 Console(dll),选择Dll。

1.2  在DllDemo.cpp文件中添加这些代码。

extern "C" __declspec(dllexport) int Add(int a,intb)

{return a+b;

}

View Code

1.3 编译工程。

1.4 建立新的C#工程,选择Console应用程序,建立测试程序InteropDemo

1.5 在Program.cs中添加引用:using System.Runtime.InteropServices;

1.6 在pulic class Program添加如下代码:

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;using System.Runtime.InteropServices; //用 DllImport 需用此 命名空间

namespaceInteropDemo

{classProgram

{

[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention =CallingConvention.Cdecl)]public static extern int Add(int a, int b); //DllImport请参照MSDN

static void Main(string[] args)

{

Console.WriteLine(Add(1, 2));

Console.Read();

}

}

}

View Code

2 C#动态调用DLL

在第一节中,讲了静态调用C++动态链接,由于Dll路径的限制,使用的不是很方便,C#中我们经常通过配置动态的调用托管Dll,例如常用的一些设计模式:Abstract Factory, Provider, Strategy模式等等,那么是不是也可以这样动态调用C++动态链接呢?只要您还记得在C++中,通过LoadLibrary, GetProcess, FreeLibrary这几个函数是可以动态调用动态链接的(它们包含在kernel32.dll中),那么问题迎刃而解了,下面我们一步一步实验

2.1 将kernel32中的几个方法封装成本地调用类NativeMethod

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Runtime.InteropServices;namespaceInteropDemo

{public static classNativeMethod

{

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]public static extern intLoadLibrary(

[MarshalAs(UnmanagedType.LPStr)]stringlpLibFileName);

[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]public static extern IntPtr GetProcAddress(inthModule,

[MarshalAs(UnmanagedType.LPStr)]stringlpProcName);

[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]public static extern bool FreeLibrary(inthModule);

}

}

View Code

2.2 使用NativeMethod类动态读取C++Dll,获得函数指针,并且将指针封装成C#中的委托。原因很简单,C#中已经不能使用指针了,如下

int hModule = NativeMethod.LoadLibrary(@"c:"CppDemo.dll");

IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");

详细请参见代码

usingSystem;usingSystem.Collections.Generic;usingSystem.Text;usingSystem.Runtime.InteropServices;namespaceInteropDemo

{classProgram

{//[DllImport("CppDemo.dll", EntryPoint = "Add", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]//public static extern int Add(int a, int b);//DllImport请参照MSDN

static void Main(string[] args)

{//1. 动态加载C++ Dll

int hModule = NativeMethod.LoadLibrary(@"c:\CppDemo.dll");if (hModule == 0) return;//2. 读取函数指针

IntPtr intPtr = NativeMethod.GetProcAddress(hModule, "Add");//3. 将函数指针封装成委托

Add addFunction = (Add)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(Add));//4. 测试

Console.WriteLine(addFunction(1, 2));

Console.Read();

}///

///函数指针///

///

///

///

delegate int Add(int a, intb);

}

}

View Code

3 注意事项:

3.1 使用静态调用时必须将DLL文件和相关配置文件放于C#可执行文件同一部木之下,否则会报错;

3.2 在C#中使用DllImport必须添加   using System.Runtime.InteropServices;

3.3 C#调用DLL时需要将 Properties中平台目标 改为和生成DLL中平台一致。(一般生成dll都是Win32,所以平台目标要改为X86。)

4 数据类型问题

因为在C#中部使用非安全是没有指针数据类型,而一般使用C或C++制作的DLL,DLL中函数的参数列表会有指针类型,调用是就必须要解决或了解这一部分知识——互操作数。

转载链接:

1) https://www.cnblogs.com/Jianchidaodi/archive/2009/03/09/1407270.html

2)  https://www.cnblogs.com/zhili/archive/2013/01/14/NetInterop.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 调用 C# dll 最简方法有以下两种: 1.使用Pythonnet:Pythonnet是一个能够把 Python 和 .NET 程序集融合在一起的,可以很方便地调用 C# dll 。首先需要安装Pythonnet,在Python中导入clr模块,然后使用clr.AddReference添加dll的引用,最后就可以使用C# dll中的类和函数了。 示例代码: ```python import clr clr.AddReference("test.dll") # 添加dll引用 from test import Test # 导入C#类Test if __name__ == '__main__': t = Test() print(t.HelloWorld()) # 调用C#类Test中的HelloWorld方法 ``` 2.使用ctypes:ctypes是Python的标准之一,也可以用来调用C# dll。可以使用LoadLibrary函数加载dll,然后使用dll中的函数和类。 示例代码: ```python import ctypes # 加载dll test_dll = ctypes.WinDLL("test.dll") # 定义C#类Test中的HelloWorld函数 test_dll.Test_HelloWorld.restype = ctypes.c_char_p test_dll.Test_HelloWorld.argtypes = [] if __name__ == '__main__': print(test_dll.Test_HelloWorld().decode()) # 调用C# dll中的函数Test_HelloWorld ``` 需要注意的是,使用ctypes调用C# dll需要在C#中使用__declspec(dllexport)标记暴露函数和类,例如: ```csharp using System; using System.Runtime.InteropServices; namespace Test { public class Test { [DllImport("test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr Test_HelloWorld(); public string HelloWorld() { return Marshal.PtrToStringUni(Test_HelloWorld()); } } } ``` 以上就是Python 调用 C# dll 最简方法的详细介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值