简体   繁体   English

为什么我在 ConsoleApplication1.exe 中的 0x00000000 处出现异常异常:0xC0000005:访问冲突执行位置 0x00000000

[英]Why do I get an Exception Exception thrown at 0x00000000 in ConsoleApplication1.exe: 0xC0000005: Access violation executing location 0x00000000

I'm trying to create a very simple dll and load it to another file for learning purpose.我正在尝试创建一个非常简单的 dll 并将其加载到另一个文件以供学习。 I'm using VC++ same version for both the DLL and the C++ file.我对 DLL 和 C++ 文件使用相同版本的 VC++。 Here is my source code:这是我的源代码:

load.cpp:加载.cpp:

#include <iostream>
#include <windows.h>

using namespace std;

typedef int(__stdcall* nsum)(int a, int b);

int main(void)
{
    HINSTANCE myDll = LoadLibrary(L".\\DLL1.dll");
    nsum sum = (nsum)GetProcAddress(myDll, "sum");

    if (!myDll) {
        cout << "could not load the dynamic library" << endl;
        return EXIT_FAILURE;
    }


    int xfinal = sum(10, 20);
    cout << xfinal << endl;

    return 0;
}

and dll.cpp和 dll.cpp

#include <windows.h>
#include "pch.h"

using namespace std;

int __declspec(dllexport) __stdcall sum(int a, int b)
{
    return a + b;
}

pch.h pch.h

// pch.cpp: source file corresponding to the pre-compiled header

#include "pch.h"

// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

But still I'm getting the exception.但我仍然得到了例外。 I searched for answers but found none, so I am writing this for help我搜索了答案,但没有找到,所以我写这个寻求帮助

In the load.cpp, in HINSTANCE myDll, I can peek and see the value being set to 0x000000000.在 load.cpp 中,在 HINSTANCE myDll 中,我可以窥视并看到设置为 0x000000000 的值。 Is it the reason?是这个原因吗? If so, How can i fix it?如果是这样,我该如何解决?

Your problem is quite simple.你的问题很简单。 The exported name of your function is not sum because you are not use a C ABI .您的 function 的导出名称不是sum ,因为您没有使用 C ABI Instead, it's a mangled name ?sum@@YGHHH@Z which of course is not found by your use of GetProcAddress(myDLL, "sum");相反,它是一个错位的名称?sum@@YGHHH@Z您使用GetProcAddress(myDLL, "sum");时当然找不到它。 There is no such function sum .没有这样的 function sum As such, you are trying to invoke a function at address 0, ie exactly what the exception tells you.因此,您正试图在地址 0 处调用 function,即异常告诉您的内容。

Microsoft calls these Decorated Names rather than "mangled" but they both mean the same thing: the type information for the parameter types, calling-convention, and return value is encoded into special symbols that make up the name. Microsoft 将这些装饰名称称为“修饰名称”而不是“损坏的”,但它们的含义相同:参数类型、调用约定和返回值的类型信息被编码为构成名称的特殊符号。

A few options here to fix this problem:这里有几个选项可以解决这个问题:

  • Use the import library instead of explicit linking which will use the mangled name so you can stick with a C++ ABI.使用导入库而不是显式链接,这将使用损坏的名称,因此您可以坚持使用 C++ ABI。

  • Use a C ABI via extern "C" keeping the existing __stdcall calling convention in which case the name will be _sum@8 when building for x86 (32-bit):通过extern "C"使用 C ABI,保持现有的__stdcall调用约定,在这种情况下,为 x86(32 位)构建时,名称将为_sum@8

extern "C" int __declspec(dllexport) __stdcall sum(int a, int b)
  • Use a C ABI with extern "C" but use __cdecl which will actually result in sum for x86 (32-bit):使用带有extern "C"的 C ABI,但使用__cdecl这实际上会导致 x86(32 位)的sum
extern "C" int __declspec(dllexport) __cdecl sum(int a, int b)

For x64 there is one standard calling convention __fastcall ( __cdecl , __stdcall are just aliases for __fastcall ).对于 x64,有一个标准的调用约定__fastcall__cdecl__stdcall只是__fastcall的别名)。 In that, just using extern "C" will result in the name sum for any of those calling conventions.在那里,仅使用extern "C"将导致任何这些调用约定的名称sum The only case that results in 'mangled' exports using a C ABI for x64 then is extern "C" __vectorcall .使用 x64 的 C ABI 导致“损坏”导出的唯一情况是extern "C" __vectorcall

Be sure to update your typedef to match the calling convention you are using if you change it.如果您更改它,请务必更新您的 typedef 以匹配您正在使用的调用约定。

Second, you should add more error-checking:其次,您应该添加更多错误检查:

HMODULE myDll = LoadLibrary(L".\\DLL1.dll");
if (!myDll) {
    cout << "could not load the dynamic library" << endl;
    return EXIT_FAILURE;
}

nsum sum = (nsum)GetProcAddress(myDll, "sum");
if (!sum) {
    cout << "could not find the export" << endl;
    return EXIT_FAILURE;
}

If you are using C++11 or later (Visual Studio 2012 or later), then auto sum = reinterpret_cast<nsum>(reinterpret_cast<void*>(GetProcAddress(myDll, "sum")));如果您使用 C++11 或更高版本(Visual Studio 2012 或更高版本),则auto sum = reinterpret_cast<nsum>(reinterpret_cast<void*>(GetProcAddress(myDll, "sum"))); is better.更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Project0_opengl.exe 中的 0x00000000 处抛出异常:0xC0000005:访问冲突执行位置 0x00000000 - Exception thrown at 0x00000000 in Project0_opengl.exe: 0xC0000005: Access violation executing location 0x00000000 在 CobwebDiagram.exe 中的 0x00000000 处引发异常:0xC0000005:访问冲突执行位置 0x00000000 - Exception thrown at 0x00000000 in CobwebDiagram.exe: 0xC0000005: Access violation executing location 0x00000000 c++ 在 ConsoleApplication1.exe 中的 0x7A45FF80 (ucrtbased.dll) 处抛出异常:0xC0000005:访问冲突读取位置 0x00000000 - c++ Exception thrown at 0x7A45FF80 (ucrtbased.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation reading location 0x00000000 0xC0000005:访问冲突执行位置0x00000000 - 0xC0000005: Access violation executing location 0x00000000 在0xC0000005中的0x6ececafa出现未处理的异常:访问冲突写入位置0x00000000 - Unhandled Exception as at 0x6ececafa in 0xC0000005 : Access violation writing location 0x00000000 0xC0000005:访问冲突读取位置0x00000000 - 0xC0000005: Access violation reading location 0x00000000 Project4.exe中0x00998876处的首次机会异常:0xC0000005:访问冲突写入位置0x00000000 - First-chance exception at 0x00998876 in Project4.exe: 0xC0000005: Access violation writing location 0x00000000 NVIDIA未处理的异常,位于0x002a2da2中 <work.exe> 0xC0000005:访问冲突读取位置0x00000000 - NVIDIA Unhandled exception at 0x002a2da2 in <work.exe>0xC0000005: Access violation reading location 0x00000000 Engine.exe中0x00000000的未处理异常:0xC0000005:访问冲突 - Unhandled exception at 0x00000000 in Engine.exe: 0xC0000005: Access violation 0xC0000005:访问冲突读取位置0x00000000 - 0xC0000005: Access violation reading location 0x00000000
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM