简体   繁体   English

C++ 成员变量未初始化

[英]C++ member variable is not initialized

I have been tasked to make available a C++ codebase to a .NET application.我的任务是向 .NET 应用程序提供 C++ 代码库。 The C++ code is used in production for a couple of years and runs without issues. C++ 代码在生产中使用了几年并且运行没有问题。

I packed the C++ code in a dll and built a C based API to make it available to .NET through P/Invoke. I packed the C++ code in a dll and built a C based API to make it available to .NET through P/Invoke.

If I test the API through a C based test application everything works as expected.如果我通过基于 C 的测试应用程序测试 API,一切都会按预期工作。 If I test the API from a C# application then the application hangs.如果我从 C# 应用程序测试 API,则应用程序挂起。 During debug I discovered that a C++ member variable is simply not initialized although the code to initialize it is executed.在调试期间,我发现 C++ 成员变量根本没有初始化,尽管执行了初始化它的代码。

The C++ class looks something like this: C++ class 看起来像这样:

template<class T> class Product
{
    enum product_status
    {
        alpha,
        beta,
        production
    };

public:
    explicit Product(T& src) : source(&src), status(alpha) { }

    void bind(T& src) { source = &src; }
    
    void reset() 
    { 
        source->reset(); 
        status = alpha;
    }

private:
    Product(const Product<T>&);
    const Product<T>& operator = (const Product<T>&);

    T* source;
    product_status status;
};

A variable of type Product is declared like this in an exported C method: Product 类型的变量在导出的 C 方法中声明如下:

void ProcessProduct(Type1* c1, Type2* c2)
{
    //
    // Do stuff
    //
    Product<Factory> p1(f1);
    //
    // Do stuff
    //
}

After the line above is executed the status member variable in p1 is still uninitialized.执行上述行后,p1 中的状态成员变量仍未初始化。 This happens only if the API is called from .NET, if the API is called from the C test application everything is initialized as expected.仅当从 .NET 调用 API 时,如果从 Z0D61F8370CAD1D083A14FZ 调用 API 时,才会发生这种情况。

The ProcessProduct method is declared in C# like this: ProcessProduct 方法在 C# 中声明如下:

    [DllImport("product.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void ProcessProduct(IntPtr c1, IntPtr c2);

My C++ knowledge is basic so I'm not sure what I'm missing.我的 C++ 知识是基本的,所以我不确定我缺少什么。 I'm using Visual Studio 2019 (16.6.3) on Windows 10. Problem appears in Debug x86, I haven't got to test it on x64.我在 Windows 10 上使用 Visual Studio 2019 (16.6.3)。问题出现在调试 x86 中,我没有在 x64 上测试它。

I finally managed to find out the problem and fix it.我终于设法找出问题并解决它。

As I said the C++ codebase is stable for a few years and already runs in production without issues so I had no reason to modify it.正如我所说,C++ 代码库已经稳定了几年,并且已经在生产中运行而没有问题,所以我没有理由修改它。

After I developed the C based API I tested it using a C application and it worked just fine.在我开发了基于 C 的 API 之后,我使用 C 应用程序对其进行了测试,它工作得很好。 After that I started working on the C# application and the API started crashing or hanging.之后,我开始研究 C# 应用程序,而 API 开始崩溃或挂起。 This is what puzzled me, the API was working from the C application but not from the C#.这让我感到困惑,API 在 C 应用程序中工作,但不是在 C# 中工作。 The truth is I did not test again the C application after I started working on the C# part.事实上,在我开始研究 C# 部件后,我没有再次测试 C 应用程序。
The problem appeared because I added a 'pragma pack' directive to map some structure from C to C#.出现问题是因为我在 map 中添加了一个“pragma pack”指令,从 C 到 C# 的某些结构。 Instead of adding it just for these structures I added it in a header file which was included before other header files and this pragma directive messed up the C++ codebase.我不是只为这些结构添加它,而是将它添加到 header 文件之前包含的 header 文件中,并且这个 pragma 指令弄乱了 C++ 代码库Truth be told, Visual Studio generated several warnings related to pragma pack inconsistencies but I ignored them initially.说实话,Visual Studio 生成了几个与编译指示包不一致相关的警告,但我最初忽略了它们。

Some styles may be offuscating the problem, first make put product_status outside template ( its not dependent of T ), second "class enum" may helo disambiguate alpha ( ther is no way I can tell, bul may exists something else callled alpha somewhere in your code )一些 styles 可能会混淆问题,首先将 product_status 放在模板之外(它不依赖于 T ),第二个“类枚举”可能会消除 alpha 歧义(我无法判断,bul 可能在您的某处存在其他称为 alpha 的东西代码 )

You may "delete" the copy constructor and assignment operator.您可以“删除”复制构造函数和赋值运算符。

You might be creating something called "handler class", and if it´s the case, if the class is a "product" it should be returned from a function of a factory, not have a pointer to one.您可能正在创建称为“处理程序类”的东西,如果是这种情况,如果 class 是“产品”,它应该从工厂的 function 返回,没有指向一个的指针。 Try discover if you can use a shered_ptr or a unique_ptr instead a "Product"尝试发现是否可以使用 shered_ptr 或 unique_ptr 而不是“产品”

https://godbolt.org/z/55c9TW https://godbolt.org/z/55c9TW

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

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