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

 更新时间:2025年10月30日 09:54:09   作者:贪嘴  
在开发过程中,我们经常需要调用一些非托管的DLL库,比如用Delphi编写的DLL,本文将介绍两种在C#中调用非托管DLL的方法,并通过代码示例介绍的非常详细,需要的朋友可以参考下

示例DLL

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

library testDLL;

uses
  SysUtils,
  Dialogs,
  Classes;

{$R *.res}

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

exports
  MyFunction;

begin
end.

方式一:直接调用

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

[DllImport("testDLL.dll")]
static extern int MyFunction(int a);

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

int i = MyFunction(123);

方式二:使用本地委托

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

辅助方法

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

// 辅助方法:加载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中方法参数一致的委托:

public delegate int MyFunctionDelphiDelegate(int param1);

使用委托调用方法

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

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库,满足不同的开发需求。

到此这篇关于C#调用非托管dll的两种方式详解的文章就介绍到这了,更多相关C#调用非托管dll内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解C#中回调函数

    深入理解C#中回调函数

    回调函数是一种在编程中常用的概念,本文将介绍回调函数的概念、语法和应用,并讨论如何设计优化和重用回调函数,以及它们在并发编程中的用途,感兴趣的可以了解一下
    2024-02-02
  • C#实现大文件分片上传完整指南

    C#实现大文件分片上传完整指南

    本文介绍了大文件分片上传的核心思路及其在前后端的的实现,前端将文件切割成多个小段,逐个发送到服务端暂存;服务端按顺序合并还原,文中还详细描述了数据库设计、断点续传、合并逻辑、并发优化等方面,并给出了一些注意事项和建议选择方案,需要的朋友可以参考下
    2026-04-04
  • C#读取Excel并转化成XML的方法

    C#读取Excel并转化成XML的方法

    这篇文章主要介绍了C#读取Excel并转化成XML的方法,实例分析了C#操作Excel及XML文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04
  • C# 基于NAudio实现对Wav音频文件剪切(限PCM格式)

    C# 基于NAudio实现对Wav音频文件剪切(限PCM格式)

    本文主要介绍了C#基于NAudio工具对Wav音频文件进行剪切,可以将一个音频文件剪切成多个音频文件(限PCM格式),感兴趣的小伙伴可以学习一下
    2021-11-11
  • C#面向对象设计原则之组合/聚合复用原则

    C#面向对象设计原则之组合/聚合复用原则

    这篇文章介绍了C#面向对象设计原则之组合/聚合复用原则,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 使用C#代码实现拆分PowerPoint演示文稿

    使用C#代码实现拆分PowerPoint演示文稿

    PowerPoint 演示文稿是各类工作和交流中常用的重要工具,本文介绍了如何在 .NET 环境中使用 C# 拆分 PowerPoint 演示文稿,文章的示例代码讲解详细,有需要的小伙伴可以参考下
    2026-05-05
  • 在C#中为文本内容添加行号的多种方法

    在C#中为文本内容添加行号的多种方法

    在C#开发中,无论是进行代码审查、分析日志文件,还是生成规范的文档报告,为文本内容添加行号都是一项常见的需求,本文将深入探讨如何在C#中高效、准确地为文本内容添加行号的多种方法,帮助你找到最适合自己的解决方案,需要的朋友可以参考下
    2025-11-11
  • C#实现将PPT文档转换为PDF格式的三种方法

    C#实现将PPT文档转换为PDF格式的三种方法

    本文介绍了使用C#实现PPT转 PDF 的三种实用方法,包括单个文件转换,批量转换以及加密 PDF 转换,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2026-01-01
  • C#编程:List.ForEach与foreach循环的对比分析

    C#编程:List.ForEach与foreach循环的对比分析

    这篇文章主要介绍了C#编程:List.ForEach与foreach循环的对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • .Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用

    .Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用

    中午没事,把去年刚毕业那会画的几张图翻出来了,大概介绍Winform应用程序运行的过程,以及TCP协议在Winform中的应用。感兴趣的朋友可以了解下;如果有Windows消息机制等基础,很好理解这两张
    2013-01-01

最新评论