首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# GetProcAddress返回零

C# GetProcAddress返回零
EN

Stack Overflow用户
提问于 2010-09-21 02:24:38
回答 4查看 15.2K关注 0票数 14

由于某些原因,每当我的C# .NET 2.0应用程序调用GetProcAddress时,它总是返回零。

代码语言:javascript
复制
public class MyClass
{
    internal static class UnsafeNativeMethods
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern bool SetDllDirectory(string lpPathName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    }

    private void MyFunc()
    {
        IntPtr _dllHandle;
        IntPtr _fptr;
        string _fullPath = ".\\mydll.dll";
        string _procName = "MyDllFunc";

        _dllHandle = UnsafeNativeMethods.LoadLibrary(_fullPath);
        _fptr = UnsafeNativeMethods.GetProcAddress(_dllHandle, _procName); // <-- Always returns zero.
    }
}

我确信函数名的拼写是正确的,并且_fullPath大概是正确的,因为_dllHandle总是被分配一个非零值。如果您能提供任何见解,我们将不胜感激。谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-09-21 02:38:14

GetProcAddress只有ANSI风格,因此我们通过告诉运行时在编组字符串参数时始终使用ANSI来帮助运行时。我们还防止运行库查找不存在的GetProcAddressA,因为C#的默认设置是将ExactSpelling设置为false。

http://www.pinvoke.net/default.aspx/kernel32.getprocaddress

票数 19
EN

Stack Overflow用户

发布于 2010-09-21 02:34:12

你真的需要添加一些错误检查。至少验证_dllHandle != IntPtr.Zero。此外,根据当前工作目录的危险程度,可以使用Assembly.GetEntryAssembly().Location获取完整的路径名。

函数名可能是错误的。导出往往是装饰性的,就像_MyDllFunc或_MyDllFunc@4。如果它是由C++编译器编译的,那就更复杂了。在DLL上使用Dumpbin.exe /exports查看真实名称。

回到错误处理,在DllImport属性中使用SetLastWin32Error。如果函数返回false或IntPtr.Zero,则抛出Win32Exception。

编辑:我看到了真正的问题。对GetProcAddress()使用CharSet.Auto是错误的。非常不幸的是,它是唯一一个只有ANSI版本的Windows API函数。您必须使用CharSet.Ansi。pinvoke.net是获取正确DllImport声明的一个好地方

票数 2
EN

Stack Overflow用户

发布于 2010-09-21 02:33:43

您还没有展示如何从DLL导出函数,但我怀疑问题在于导出的名称并不是您想象的那样。您可以运行dumpbin /exports mydll.dll查看dll的导出以验证名称。

如果您显示导出的代码片段,我可以提供更直接的建议。您可以尝试使用extern "C"修饰导出的函数,以消除作为测试的名称损坏。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3754264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档