繁体   English   中英

程序未按顺序通过构造函数,从而导致未初始化的变量

[英]Program does not go in order through constructor thus leading to uninitialized variables

在尝试使用Qt 5.4和MSVC 2013 32bit在发布模式下编译程序后,我发现了此问题。 到目前为止,在调试中一切正常,但是每次尝试在发行版中运行时,都会抛出错误代码:0xc0000409。 看起来这通常意味着在某处有初始化变量,因此我在代码中设置了断点以查看问题所在。 我发现的是,在我的一个类的构造函数中,如果我在每行上设置一个断点,则断点将从中间的某处开始,并跳过为该对象初始化变量的位置。 这是代码:

#ifndef AD5932DDS_H
#define AD5932DDS_H

#include "adicyusbusb4.h"
#include <QObject>
#include "picosignal.h"
#include <QLibrary>


class AD5932DDS : public QObject
{
Q_OBJECT
public:
    AD5932DDS(QObject *parent = 0);
    ~AD5932DDS();

private:
    QLibrary *myLib;

    unsigned int handle;

    VendorRequestFunction Vendor_Request;
    DisconnectFunction Disconnect;
    SearchFunction Search_For_Boards;
    ConnectFunction Connect;
    DownloadFWFunction Download_Firmware;

};


#endif // AD5932DDS_H




AD5932DDS::AD5932DDS(QObject *parent) : QObject(parent)
{
int searchErrorCode = 0;
int connectErrorCode = 0;
int downloadErrorCode = 0;
unsigned int num_boards = 0;
handle = 0;

char pcFilePath[] = "C:\\Users\\Jason\\Documents\\Development\\Qt\\CrackDetection\\AD593x.hex";
char path = 0;
myLib = new QLibrary;
myLib->setFileName("ADI_CYUSB_USB4.dll");
Search_For_Boards = (SearchFunction) myLib->resolve("Search_For_Boards");
Connect = (ConnectFunction) myLib->resolve("Connect");
Download_Firmware = (DownloadFWFunction) myLib->resolve("Download_Firmware");
Vendor_Request = (VendorRequestFunction) myLib->resolve("Vendor_Request");
Disconnect = (DisconnectFunction) myLib->resolve("Disconnect");
if (!Search_For_Boards || !Connect || !Download_Firmware || !Vendor_Request || !Disconnect)
{
    myLib->unload();
}

searchErrorCode = Search_For_Boards(VID, PID, &num_boards, &path);

if (num_boards > 0)
{
    connectErrorCode = Connect(VID, PID, path, &handle);
    if (connectErrorCode == 0)
    {
        downloadErrorCode = Download_Firmware(handle, pcFilePath2);
    }
}
}

如果我逐步调试这些代码,则中断的第一行是上面的行

char pcFilePath[] = "C:\\Users\\Jason\\Documents\\Development\\Qt\\CrackDetection\\AD593x.hex";

然后它将返回顶部,然后继续正常运行,一切正常。

但是,在释放模式下

QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO

在.pro文件中以在调试发行版时允许断点,第一个要命中的断点是

handle = 0;

从这里开始,向下跳过它上面的初始化,以便

myLib = new QLibrary;
myLib->setFileName("ADI_CYUSB_USB4.dll");

在继续之前,它两次都击中了这两个位置。 我注意到的一件事是,即使

Search_For_Boards = (SearchFunction) myLib->resolve("Search_For_Boards");
Connect = (ConnectFunction) myLib->resolve("Connect");
Download_Firmware = (DownloadFWFunction) myLib->resolve("Download_Firmware");
Vendor_Request = (VendorRequestFunction) myLib->resolve("Vendor_Request");
Disconnect = (DisconnectFunction) myLib->resolve("Disconnect");

运行时,如果我检查这些名称和值,则这些列表中的每一个都在value下。 因此,这使我认为也许每个问题都源于尝试访问此dll的原因。

该dll来自https://ez.analog.com/thread/11089 ,在经过反复试验后,我无法弄清该dll在不提供静态库或头文件的情况下如何使用原型。 我所做的是在这样的头文件中创建自己的原型:

#ifndef ADICYUSBUSB4_H
#define ADICYUSBUSB4_H

const unsigned int VID = 0x0456;
//const unsigned int PID = 0xB20B; // EVAL-AD5932EBZ
const unsigned int PID = 0xB205; // EVAL-AD5930EBZ
const unsigned char WRITE = 0xDD;
const unsigned char SET_STANDBY_PIN = 0xDC;
const unsigned char CLEAR_STANDBY_PIN = 0xDB;
const unsigned char PULSE_CONTROL_PIN = 0xDA;
const unsigned char SET_CONTROL_PIN = 0xD9;
const unsigned char CLEAR_CONTROL_PIN = 0xD8;
const unsigned char PULSE_INTERRUPT_PIN = 0xD7;


typedef unsigned int (*SearchFunction) (unsigned int, unsigned int, unsigned int *, char *);
typedef int (*ConnectFunction) (unsigned int, unsigned int, char, unsigned int *);
typedef int (*DownloadFWFunction) (unsigned int, char []);
typedef int (*VendorRequestFunction) (unsigned int, unsigned char, unsigned short, unsigned short, unsigned char, unsigned short, unsigned char *[]);
typedef int (*DisconnectFunction) (unsigned int);

#endif // ADICYUSBUSB4_H 

该方法在调试模式下效果很好,但是有些东西不适合发布。

因此,要么我不正确地处理了这个dll(尽管它在调试模式下工作得很好),要么我的程序出于某种未知原因而跳过了一些变量初始化。

在启用优化的情况下编译时,不要依赖断点或单步执行。 优化器将更改,重新排序或删除语句。 不要花费太多时间来分析经过优化而编译的程序的流程。

  • QLibrary是否在某种程度上失败了? 检查isLoaded()并记录各种resolve()调用的返回值。 如果发生故障,您正在调用unload() ,但是您正在愉快地执行其余的操作,试图取消对空指针的引用。

  • 您能确切知道它崩溃的地方吗? 尝试使用无缓冲流(例如std::cerr在每个语句之间向控制台输出内容。

可能是因为您的工作目录不同以及DLL无法加载而变得愚蠢。

我相信0xc0000409表示堆栈损坏,这可能是由各种原因引起的,而不仅仅是未初始化的变量。

由于您注意到必须手动创建DLL标头,因此它可能与DLL实际实现的方式不完全匹配。 除了诸如参数计数/类型和返回类型之类的东西外,还有调用约定。 由于您未指定任何一个,因此您将获得MSVC的默认值。 但是,如果该DLL是使用选择了不同约定的东西编译的,则该不匹配将导致问题。

实际上,可能的结果是堆栈损坏。 我不能肯定地说这是您的问题,但我相信这将与您的0xc0000409错误保持一致。

理想情况下,该DLL的提供者将能够提供正确的信息。 (或者至少,如果您可以找出他们使用了什么编译器,则可以研究其默认调用约定。)

但是,如果他们不能或不会,那么你可能不得不求助于尝试不同的人而看似正常工作眼见。

您是在构造函数内部声明变量。 构造函数仅用于初始化变量,因此请尝试更改它(声明在构造函数中没有任何作用,尤其是默认值)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM