从.NET动态解析C stdlib函数

本文关键字:stdlib 函数 NET 动态 | 更新日期: 2023-09-27 18:29:30

我想在运行时从.NET代码中解析类似于C stdlib(如malloc)的函数的地址(这样我就可以为VM JIT调用这些地址的机器代码)。我认为我应该使用提供kernel32.dll的LoadLibraryGetProcAddress,但这不起作用。使用F#交互式我得到:

> [<DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)>]
  extern IntPtr LoadLibrary(string fileName);;
val LoadLibrary : string -> IntPtr
> [<DllImport("kernel32.dll", CharSet=CharSet.Ansi, SetLastError=true)>]
  extern uint32 GetProcAddress(IntPtr hModule, string fn);;
val GetProcAddress : IntPtr * string -> uint32
> let kernel32 = LoadLibrary @"kernel32.dll";;
val kernel32 : IntPtr = 1993146368n
> let malloc = GetProcAddress(kernel32, "malloc");;
val malloc : uint32 = 0u

因此,这似乎已经获得了DLL的句柄,但试图解析malloc却返回了一个NULL指针。

我该怎么做?

从.NET动态解析C stdlib函数

我不认为mallockernel32.dll的一部分。但是,如果我没有记错的话,所有malloc实现最终都会深入到HeapAlloc,它在kernel32.dll中可用。

AFAIK malloc不是kernel32.dll的一部分。它是MS C运行时DLL的一部分,因为您没有提供任何关于如何/在哪里使用它的详细信息,只有一些带有相关信息的链接:

  • http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx
  • http://www.codeproject.com/Articles/20248/A-Short-Story-about-VC-CRT

基本上,您必须加载相应的DLL,然后解析所需的函数,例如:

let SomeMSCRT = LoadLibrary @"SomeMSCRT.dll";;
let malloc = GetProcAddress(SomeMSCRT, "malloc");;

不过有一点需要注意:

根据你想做的事情,你可能会遇到严重且难以调试的问题——例如,使用F#中的malloc是IMHO的坏主意。。。您需要记住,C运行时需要正确初始化(在MS CRT的情况下,您需要首先调用CRT_INIT)等。C运行时不知道任何.NET细节,因此可能导致不稳定的行为。。。特别是因为CLR可能在内部使用CRT(可能是不同的版本)。。。

另一点:

在运行时生成机器代码并通过跳转到该内存区域来执行该代码需要采取多种安全措施(取决于Windows版本等)。您可能需要将相应的内存段标记为"可执行",这在C运行时是不可能的,只能使用具有适当权限的Windows API调用(如VirtualAllocEx)。。。请在此处和此处查看起点。

我想解析函数的地址,比如C stdlib 中的函数

这是你的问题。你说的好像有一个C运行库。事实上有很多。每个编译器都提供自己的,有几种不同的风格(调试、发布、静态链接、动态链接),所有这些都是相互不兼容的。

如果你知道你想用哪一个,你的问题的答案就会变得显而易见。

如果希望在所有Windows应用程序之间共享操作系统提供的库,则kernel32.dll是正确的查找位置,但函数符合Win32 API规范,而不是ANSI或ISO C标准。