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

Ziv*_*ivF 7 c c# dll interop cdecl

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

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

有没有办法直接从.NET获取这个export-functions-list,而不必使用外部命令行工具?

谢谢

Han*_*ans 8

据我所知,.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);
}
Run Code Online (Sandbox Code Playgroud)

为了保持示例简单,我没有使用该 SymEnumSymbols函数.我也没有使用像SafeHandle.Net框架这样的类这样的例子.如果您需要该SymEnumSymbols功能的示例 ,请告诉我.