gpt4 book ai didi

c++ - Borland C++ Builder LoadFromResourceID 导致 EAccess 违规

转载 作者:太空宇宙 更新时间:2023-11-04 12:45:34 26 4
gpt4 key购买 nike

我正在使用 Borland C++Builder 5 编写游戏程序。我正在尝试从我创建的资源文件中加载位图。我无法从中加载位图按 ID 或按名称的资源文件。它将从文件加载,但我想要使用资源文件。从 ID 或名称加载会导致在运行时出现以下错误消息:

Project HoldemProbs.exe raised exception class EAcessViolation with message 'Access violation at address 0043F66E in module 'HoldemProbs.exe'. Read of address 000003EB. Process stopped. Use Step or Run to continue.

我是 C++ 和 C++Builder 的新手,我确信我做错了什么。我只是不知道是什么。我认为它可能与 HInstance 值有关,但我不知道是什么。

下面是相关的代码片段:

ResRC.h

#ifndef RESRC_H 
#define RESRC_H
#define RC_REDBACK 1000
#endif

红背.rc

RC_REDBACK BITMAP "<MYSOURCEPATH>\RedBack.bmp"

HoldemProbs.cpp

#include <vcl.h>
#pragma hdrstop
USERES("HoldemProbs.res");
USEFORM("..\Source\HoldemCalc.cpp", Form1);
USERES("..\Source\RedBack.res");

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = "HoldemEval";
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}

扑克计算器.cpp

#include <vcl.h>
#include <cstring.h>
#include <HoldemEval.hpp>
#include <Graphics.hpp>
#pragma hdrstop
#pragma resource "*.dfm"
#include <Graphics.hpp>
#include <ResRC.h>
#include "HoldemCalc.h"
#include <string>

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
CardBackTst(); //Run test of card back bitmap useage
}

CardBackTst.cpp

void CardBackTst(void){
Graphics::TBitmap* RedBack = new Graphics::TBitmap;
Form1 -> Debug -> Text = DEBUGTEXT; //See below for DEBUGTEXT
RedBack -> LoadFromResourceID ((ARG1),RC_REDBACK); //See below for ARG1
}

有一个名为Debug 的编辑框,用于显示调试信息。在不同的时间,DEBUGTEXT 是(没有周围的 "):

"(int)(GetModuleHandle(NULL)"
"reinterpret_cast<int>(HInstance)"
"(int)HInstance"
"(int)(GetModuleHandle("<MYFINALPATH>\\HoldemProbs.exe"))" // ANSI string
"RC_REDBACK" (This yielded the correct value -- 1000)
"reinterpret_cast<int>(RedBack -> Handle)"
"(int)(Form1 -> Handle)"

在不同的时间,ARG1 一直是上述 DEBUGTEXT 的每个值,RC_REDBACK 除外。所有这些都导致了 EAccessViolation 错误。

下面从资源名加载的语句已经被使用每个 ARG1 值,具有相同的 EAcessViolation 结果:

RedBack -> LoadFromResourceName ((ARG1),"MYPATH\\RedBack.bmp"); 

但是,以下从实际位图文件加载的 LoadFromFile() 语句确实有效:

RedBack -> LoadFromFile("MYPATH\\RedBack.bmp");

最佳答案

我看到这段代码有两个问题:

  • RedBack.rc 没有#include "ResRC.h" 语句:

    #include "ResRC.h" // <-- add this!
    RC_REDBACK BITMAP "<MYSOURCEPATH>\RedBack.bmp"

    否则,RC_REDBACK 将不会被#defined,因此位图资源将由文字名称"RC_REDBACK" 标识而不是 ID 号 1000。因此,您将不得不使用 LoadFromResouceName() 而不是 LoadFromResourceID():

    RedBack->LoadFromResourceName((unsigned)HInstance, "RC_REDBACK");

    使用资源查看器工具来验证您的资源在最终可执行文件中的实际识别方式。

  • CardBackTst() 内部,全局 Form1 指针可能尚未分配,因为 TForm1 对象仍处于正在 build 中。 CardBackTst() 不应该 完全依赖于全局指针。它应该将 Form 指针作为输入参数:

    //#include "ResRC.h"

    void CardBackTst(TForm1 *Form) {
    Graphics::TBitmap* RedBack = new Graphics::TBitmap;
    if (Form) Form->Debug->Text = DEBUGTEXT;
    //RedBack->LoadFromResourceID((unsigned)HInstance, RC_REDBACK);
    RedBack->LoadFromResourceName((unsigned)HInstance, "RC_REDBACK");
    }

    ...

    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    CardBackTst(this);
    }

    更好的解决方案是直接传入 TEdit 而不是 TForm 本身:

    //#include "ResRC.h"

    void CardBackTst(TEdit *Debug) {
    Graphics::TBitmap* RedBack = new Graphics::TBitmap;
    if (Debug) Debug->Text = DEBUGTEXT;
    //RedBack->LoadFromResourceID((unsigned)HInstance, RC_REDBACK);
    RedBack->LoadFromResourceName((unsigned)HInstance, "RC_REDBACK");
    }

    ...

    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    CardBackTst(Debug);
    }

    或者,改用回调函数:

    //#include "ResRC.h"

    typedef void __fastcall (__closure *TCardDebugProc)(const String &);

    void CardBackTst(TCardDebugProc DebugProc) {
    Graphics::TBitmap* RedBack = new Graphics::TBitmap;
    if (DebugProc) DebugProc(DEBUGTEXT);
    //RedBack->LoadFromResourceID((unsigned)HInstance, RC_REDBACK);
    RedBack->LoadFromResourceName((unsigned)HInstance, "RC_REDBACK");
    }

    ...

    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    CardBackTst(&LogDebug);
    }

    void __fastcall TForm1::LogDebug(const String &DebugText)
    {
    Debug->Text = DebugText;
    }

关于c++ - Borland C++ Builder LoadFromResourceID 导致 EAccess 违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51813560/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com