C# 获取非托管 C dll 导出列表

标签 c# c dll interop cdecl

我有一个带有导出函数的 C dll

我可以使用命令行工具 dumpbin.exe/EXPORTS 来提取导出函数的列表,然后在我的 C# 代码中使用它们来(成功)调用这些函数。

有没有办法直接从 .NET 获取这个导出函数列表,而无需使用外部命令行工具?

谢谢

最佳答案

据我所知,.Net Framework 中没有类 提供您需要的信息。

但是您可以使用.Net 平台的平台调用服务(PInvoke)来 使用 Win32 dbghelp.dll DLL 的功能。这个 DLL 是 Windows 平台调试工具。 dbghelp DLL 提供 一个名为 SymEnumerateSymbols64 的函数,它允许您枚举所有 动态链接库的导出符号。还有一个 称为 SymEnumSymbols 的新函数也允许枚举 导出符号。

下面的代码显示了一个关于如何使用 SymEnumerateSymbols64 的简单示例 功能。

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, [MarshalAs(UnmanagedType.Bool)]bool fInvadeProcess);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymCleanup(IntPtr hProcess);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile,
     string ImageName, string ModuleName, long BaseOfDll, int DllSize, IntPtr Data, int Flags);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymEnumerateSymbols64(IntPtr hProcess,
   ulong BaseOfDll, SymEnumerateSymbolsProc64 EnumSymbolsCallback, IntPtr UserContext);

public delegate bool SymEnumerateSymbolsProc64(string SymbolName,
      ulong SymbolAddress, uint SymbolSize, IntPtr UserContext);

public static bool EnumSyms(string name, ulong address, uint size, IntPtr context)
{
  Console.Out.WriteLine(name);
  return true;
}    

static void Main(string[] args)
{
  IntPtr hCurrentProcess = Process.GetCurrentProcess().Handle;

  ulong baseOfDll;
  bool status;

  // Initialize sym.
  // Please read the remarks on MSDN for the hProcess
  // parameter.
  status = SymInitialize(hCurrentProcess, null, false);

  if (status == false)
  {
    Console.Out.WriteLine("Failed to initialize sym.");
    return;
  }

  // Load dll.
  baseOfDll = SymLoadModuleEx(hCurrentProcess,
                              IntPtr.Zero,
                              "c:\\windows\\system32\\user32.dll",
                              null,
                              0,
                              0,
                              IntPtr.Zero,
                              0);

  if (baseOfDll == 0)
  {
    Console.Out.WriteLine("Failed to load module.");
    SymCleanup(hCurrentProcess);
    return;
  }

  // Enumerate symbols. For every symbol the 
  // callback method EnumSyms is called.
  if (SymEnumerateSymbols64(hCurrentProcess,
      BaseOfDll, EnumSyms, IntPtr.Zero) == false)
  {
    Console.Out.WriteLine("Failed to enum symbols.");
  }

  // Cleanup.
  SymCleanup(hCurrentProcess);
}

为了使示例简单,我没有使用 SymEnumSymbols 函数。我也做了这个例子 不使用诸如 SafeHandle 类之类的类 .Net 框架。如果你需要一个例子 SymEnumSymbols 函数,请告诉我。

关于C# 获取非托管 C dll 导出列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18249566/

相关文章:

c# - SQL Server XML 数据类型在 .NET 中转换成什么?我如何将它转换成 XmlDocument?

c - 为什么在 c 中 sizeof(0.7)=8 字节?

c++ - 生成DLL时发生C++错误:const wchar_t *类型的参数与LPWSTR类型的参数不兼容

c - 带 char ** 的自由结构数组

c# - 将 DLL 嵌入已编译的可执行文件中

c++ - 切片 DLL 句柄类

c# - "j8"的类型初始值设定项引发异常 Visual Studio 2012

javascript - 在 JavaScript 中加密不会在 C# 中解密

c# - RavenDB 服务器模式性能

c - 序列化函数中的段错误