C#调用非托管dll的两种方式


C#调用非托管DLL的两种方式

在开发过程中,我们经常需要调用一些非托管的DLL库,比如用Delphi编写的DLL。本文将介绍两种在C#中调用非托管DLL的方法。

示例DLL

首先,我们有一个Delphi编写的DLL,它导出了一个名为MyFunction的方法:

delphi 复制代码
library testDLL;

uses
  SysUtils,
  Dialogs,
  Classes;

{$R *.res}

function MyFunction(param1: Integer): Integer; stdcall;
begin
  Result := param1 + 1;
end;

exports
  MyFunction;

begin
end.

方式一:直接调用

这是最常见的调用方式,通过DllImport属性直接导入非托管方法。

csharp 复制代码
[DllImport("testDLL.dll")]
static extern int MyFunction(int a);

然后,你可以直接调用这个方法:

csharp 复制代码
int i = MyFunction(123);

方式二:使用本地委托

另一种方法是将非托管方法转换为本地委托。这种方式更灵活,但需要更多的代码。

辅助方法

首先,我们需要一些辅助方法来加载和卸载DLL:

csharp 复制代码
// 辅助方法:加载DLL
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);

// 辅助方法:卸载DLL
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary(IntPtr hModule);

// 获取方法指针
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

定义委托

接下来,定义一个与DLL中方法参数一致的委托:

csharp 复制代码
public delegate int MyFunctionDelphiDelegate(int param1);

使用委托调用方法

最后,使用委托来调用非托管方法:

csharp 复制代码
void run()
{
    // 加载DLL
    IntPtr dllHandle = LoadLibrary("testDLL.dll");
    if (dllHandle == IntPtr.Zero)
    {
        var err = Marshal.GetHRForLastWin32Error();
    }

    // 获取方法指针
    IntPtr functionPointer = GetProcAddress(dllHandle, "MyFunction");

    MyFunctionDelphiDelegate my = (MyFunctionDelphiDelegate)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(MyFunctionDelphiDelegate));
    // 调用方法
    int i = my(1);

    // 释放DLL
    FreeLibrary(dllHandle);
}

注意事项

  1. 位数一致性:确保你的程序和DLL的位数(32位或64位)保持一致。
  2. 字符串参数 :Delphi方法中的参数和返回值如果是字符串,不能直接使用String类型。需要使用PAnsiCharPChar,并搭配StrNew使用。
  3. 返回值 :如果方法返回值为字符串,需要使用IntPtr类型,并通过Marshal.PtrToStringAnsi(strIntPtr)来获取实际的字符串值。

通过这两种方式,你可以灵活地在C#中调用非托管的DLL库,满足不同的开发需求。


相关推荐
小猪快跑爱摄影7 分钟前
【AutoCad 2025】【C#】零基础教程(三)——获取选中的 Entity 插件 =》 初识 Entity 派生类
c#·autocad
鸡吃丸子8 分钟前
React Native入门详解
开发语言·前端·javascript·react native·react.js
盼哥PyAI实验室11 分钟前
Python YAML配置管理:12306项目的灵活配置方案
开发语言·python
漂亮的小碎步丶12 分钟前
【启】Java中高级开发51天闭关冲刺计划(聚焦运营商/ToB领域)
java·开发语言
hd51cc19 分钟前
MFC运行时
开发语言·mfc
wniuniu_22 分钟前
ceph一些细节处理
开发语言·ceph
hd51cc22 分钟前
异常处理(Exception Handling)
开发语言
SadSunset24 分钟前
(19)Bean的循环依赖问题
java·开发语言·前端
JIngJaneIL27 分钟前
基于Java+ vue图书管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
Wpa.wk43 分钟前
自动化测试-鼠标+键盘操作 - Actions高级控件
java·开发语言·测试工具·自动化·计算机外设·actions·高级控件