Surubelnita
Surubelnita

Reputation: 107

C++ member variable is not initialized

I have been tasked to make available a C++ codebase to a .NET application. The C++ code is used in production for a couple of years and runs without issues.

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. If I test the API from a C# application then the application hangs. During debug I discovered that a C++ member variable is simply not initialized although the code to initialize it is executed.

The C++ class looks something like this:

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:

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. 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.

The ProcessProduct method is declared in C# like this:

    [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. 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.

Upvotes: 1

Views: 704

Answers (2)

Surubelnita
Surubelnita

Reputation: 107

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.

After I developed the C based API I tested it using a C application and it worked just fine. After that I started working on the C# application and the API started crashing or hanging. This is what puzzled me, the API was working from the C application but not from the C#. The truth is I did not test again the C application after I started working on the C# part.
The problem appeared because I added a 'pragma pack' directive to map some structure from C to 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. Truth be told, Visual Studio generated several warnings related to pragma pack inconsistencies but I ignored them initially.

Upvotes: 1

Cleiton Santoia Silva
Cleiton Santoia Silva

Reputation: 483

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 )

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. Try discover if you can use a shered_ptr or a unique_ptr instead a "Product"

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

Upvotes: 0

Related Questions