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

C#获取非托管C dll导出的列表,c#,c,dll,interop,cdecl,C#,C,Dll,Interop,Cdecl,我有一个带有导出函数的C dll 我可以使用命令行工具dumpbin.exe/EXPORTS提取导出函数的列表,然后在我的C#代码中使用它们(成功)调用这些函数 有没有一种方法可以直接从.NET获取导出的函数列表,而不必使用外部命令行工具 谢谢据我所知,.Net Framework中没有这样的类 提供您需要的信息 但是,您可以使用.Net平台的平台调用服务(PInvoke)来 使用Win32dbghelp.dll的函数。此DLL是的一部分 Windows平台的调试工具。dbghelp DLL提供

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

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

有没有一种方法可以直接从.NET获取导出的函数列表,而不必使用外部命令行工具

谢谢

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

但是,您可以使用.Net平台的平台调用服务(PInvoke)来 使用Win32dbghelp.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
函数,请告诉我。

检查一下-我需要它,不是DLLExport,而是DLLImport,我使用LoadLibrary和GetProcAddress win32api动态使用它。问题是我从许多来源获得DLL,导出函数的名称不仅是原始函数名,还包括所有其他类型的内容,如问号和“@”,因此我需要获取所有导出函数名的列表,以查看哪个包含我要查找的名称。这不是一个选项。通常情况下,你不会发现VS中内置的没有帮助的功能。提取导出函数的名称只是工作的一小部分,你仍然需要知道参数的类型和返回值。我知道方法签名,我只是不知道它们的名称非常感谢省略信息,我已经对它进行了测试,它似乎工作得很好。不过,就功能而言,我还缺少一个功能,那就是能够为列出的每个函数名获取入口点名称,这是因为,例如,名为“GGT_RecommendMacros”的函数的入口点名为“?GGT_RecommendMacros”@@YAPADPBDPAHPAPAPAD@Z"@ ZIVF:GGTJEXPRESTMECHS @ @……是C++名称修饰。这是您的函数的入口点。请参见链接以作进一步解释。